Drf-social-oauth2: request.user is AnonymousUser

Я пытаюсь использовать drf-social-oauth2 для аутентификации и авторизации. Я настроил его, используя документацию по ссылке выше. Но документации не хватает. Я не смог найти в документации, как изменить некоторые настройки.

Когда я отправляю запрос на /auth/token/, вот какой ответ я получаю:

{
    "access_token": "KQP6l5nHezWlFO3Ixwz4IIFNUjkvEp",
    "expires_in": 36000,
    "token_type": "Bearer",
    "scope": "read write",
    "refresh_token": "rmyOZJPQE6Z1eqbpihr2Ux6YMDN1LU"
}

Но я хочу использовать JWT с пользовательскими утверждениями и не могу найти, как это сделать в документации по ссылке выше.

Мой вопрос на данный момент заключается в том, как я могу использовать JWT вместо Bearer. И как я могу включить пользовательские требования в JWT-токены, используя drf-social-oauth2 ?

Если можете, пожалуйста, укажите мне на документацию с более подробной информацией о drf-social-oauth2. Единственное, что я нашел для настройки токена, это это в этой документации.

РЕДАКТИРОВАТЬ 1

Мне удалось использовать JWT-токены, добавив ACTIVATE_JWT = True в мой settings.py файл. Мне также удалось включить пользовательские требования в токен, переопределив функцию create_token_response класса TokenView и переопределив конечную точку auth/token, как показано ниже:

from drf_social_oauth2.views import TokenView
import json
from jose import jwt
from django.conf import settings

class CustomTokenView(TokenView):
    def create_token_response(self, request):
        response_data = super().create_token_response(request)
        print("+++++++++++++++++++++++++++++++++++++++++++++")
        print(request.user)
        print(request.user.id)
        print("+++++++++++++++++++++++++++++++++++++++++++++")
        url, headers, body, status = response_data
        token_data = json.loads(body)
        access_token = token_data.get("access_token")
        decoded_token = jwt.decode(
            access_token, settings.SECRET_KEY, algorithms=["HS256"]
        )
        decoded_token["custom_claim"] = "custom_value"
        updated_access_token = jwt.encode(
            decoded_token, settings.SECRET_KEY, algorithm="HS256"
        )
        token_data["access_token"] = updated_access_token
        modified_body = json.dumps(token_data)
        return url, headers, modified_body, status

А в urls.py:

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from account.views import CustomTokenView

urlpatterns = [
    # oauth
    path("auth/token/", CustomTokenView.as_view(), name="token_obtain"),
    path("auth/", include("drf_social_oauth2.urls", namespace="drf")),
    # admin
    path("admin/", admin.site.urls),
    # user account
    path("api/account/", include("account.urls", namespace="account")),
    path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
    # api schema
    path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
    path(
        "api/schema/docs/",
        SpectacularSwaggerView.as_view(url_name="schema"),
        name="swagger-ui",
    ),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Но теперь я хочу включить информацию о пользователе в jwt-токен. Но когда я печатаю request.user и request.user.id в функции create_token_response, упомянутой выше, как показано ниже:

print("+++++++++++++++++++++++++++++++++++++++++++++")
print(request.user)
print(request.user.id)
print("+++++++++++++++++++++++++++++++++++++++++++++")

вывод:

+++++++++++++++++++++++++++++++++++++++++++++
AnonymousUser
None
+++++++++++++++++++++++++++++++++++++++++++++

Пользователем является AnonymousUser, а идентификатором - None.

Я сделал то, что хотел, сделав примерно следующее:

import json
from jose import jwt
from django.conf import settings
from oauth2_provider.models import AccessToken


class CustomTokenView(TokenView):
    def create_token_response(self, request):
        response_data = super().create_token_response(request)

        url, headers, body, status = response_data
        if status == 400:
            return response_data

        # Extract token
        token_data = json.loads(body)
        access_token = token_data.get("access_token")
        access_token_object = AccessToken.objects.get(token=access_token)

        # Extract the email from the request and get the user with that email
        user_email = access_token_object.user
        user = User.objects.get(email=user_email)

        # Decode the token and add custom claims and encode the token again
        decoded_token = jwt.decode(
            access_token, settings.SECRET_KEY, algorithms=["HS256"]
        )
        decoded_token["token_type"] = "access"
        decoded_token["user_id"] = user.id
        decoded_token["email"] = user.email
        decoded_token["exp"] = access_token_object.expires
        updated_access_token = jwt.encode(
            decoded_token, settings.SECRET_KEY, algorithm="HS256"
        )

        # Update the token with new tokens containing custom claims
        token_data["access_token"] = updated_access_token
        modified_body = json.dumps(token_data)
        response_data = url, headers, modified_body, status
        return response_data

и переопределите конечную точку auth/token/, чтобы использовать это пользовательское представление:

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from account.views import CustomTokenView

urlpatterns = [
    # oauth
    path("auth/token/", CustomTokenView.as_view(), name="token_obtain"),
    path("auth/", include("drf_social_oauth2.urls", namespace="drf")),
    # admin
    path("admin/", admin.site.urls),
    # user account
    path("api/account/", include("account.urls", namespace="account")),
    path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
    # api schema
    path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
    path(
        "api/schema/docs/",
        SpectacularSwaggerView.as_view(url_name="schema"),
        name="swagger-ui",
    ),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Вернуться на верх