drf-social-oauth2:request.user 是 AnonymousUser

问题描述 投票:0回答:1

我正在尝试使用 drf-social-oauth2 进行身份验证和授权。我使用上面链接的文档进行了设置。但缺少文档。我在文档中找不到如何更改某些设置。

当我向

/auth/token/
发送请求时,这是我得到的响应:

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

但是我想将 JWT 与自定义声明一起使用,但在上面链接的文档中找不到如何操作。

我现在的问题是如何使用 JWT 代替 Bearer。如何使用 drf-social-oauth2 在 JWT 令牌中包含自定义声明?

如果可以的话,请向我指出包含有关 drf-social-oauth2 的更多详细信息的文档。我发现自定义令牌的唯一内容是本文档中的this

编辑1

我通过在我的

ACTIVATE_JWT = True
文件中添加
settings.py
设法使用 JWT 令牌。我还设法通过覆盖
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
,ID 是
None

django django-rest-framework oauth-2.0 jwt
1个回答
0
投票

我通过做这样的事情做了我想做的事:

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)
© www.soinside.com 2019 - 2024. All rights reserved.