从 Django Rest 框架中的访问令牌获取用户详细信息 - 简单 JWT

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

我正在一个项目中使用 React 和 Django Rest 框架。我使用 Django Rest 框架简单 JWT 进行身份验证。现在,我想在用户登录后在导航栏中显示用户名。那么,在简单的 JWT 中是否有一种方法可以从身份验证后生成的访问令牌返回用户详细信息,就像 Djoser 在提供访问令牌时返回用户凭据一样?

抱歉,如果这个问题很愚蠢,但我无法在任何地方找到解决方案。

django-rest-framework django-rest-framework-simplejwt
5个回答
7
投票

如果您想获取代币所有者的信息,可以在REQUEST中查询。

class ViewProtect(APIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

    def post(self, request, format=None):
        token_user_email = request.user.email
        token_user_username = request.user.username
        pass

6
投票

关于后端,基本上我都用这个库

from restframework_simplejwt.tokens import AccessToken

函数 AccessToken() 将字符串 access_token_str 作为输入并返回对象 access_token_obj。

要获取user_id,可以使用指令

user_id=access_token_obj['user_id'].

在下面的示例中我创建了该函数

get_user_from_access_token_in_django_rest_framework_simplejwt().

这个函数只是 AccessToken() 的包装

完整代码:

#Path current file
#/blabla/django/project004/core/view.py


from restframework_simplejwt.tokens import AccessToken
from django.contrib.auth.models import User

#Example data.
#access_token_str = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU'
def get_user_from_access_token_in_django_rest_framework_simplejwt(access_token_str):
    access_token_obj = AccessToken(access_token_str)
    user_id=access_token_obj['user_id']
    user=User.objects.get(id=user_id)
    print('user_id: ', user_id )
    print('user: ', user)
    print('user.id: ', user.id )
    content =  {'user_id': user_id, 'user':user, 'user.id':user.id}
    return Response(content)

学分:

@davesque;
https://github.com/jazzband/djangorestframework-simplejwt/issues/140

更新。 我在文件中写入的字符串 access_token_str 只是一个示例。您应该将其作为参数传递。


2
投票

如果您想自定义此格式的返回数据:

{
    access: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2bl........Cj4",
    refresh: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2t.........g",
    user_id: 15,
    username: "admin"
}

您需要自定义并重写 validate() 方法:

    from rest_framework_simplejwt.views import TokenObtainPairView
    from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
    
    
    class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
        @classmethod
        def get_token(cls, user):
            token = super().get_token(user)
    
            # Add custom claims
            token["custom_field"] = "Custom value"
    
            return token
    
        def validate(self, attrs):
            data = super().validate(attrs)
    
            user = self.user
            data["user_id"] = user.id
            data["username"] = user.username
            # ... add other user information as needed
    
            return data
    
    
    class CustomTokenObtainPairView(TokenObtainPairView):
        serializer_class = CustomTokenObtainPairSerializer

网址:

from django.urls import path
from . import views
from rest_framework_simplejwt.views import TokenRefreshView

urlpatterns = [
    path("token/", views.CustomTokenObtainPairView.as_view(), name="token_obtain_pair"),
    path("token/refresh/", TokenRefreshView.as_view(), name="token_refresh"),
]

0
投票

我就是这样做的。

在 Django 上,我按照本页描述的步骤在 JWT 令牌中添加用户名:https://django-rest-framework-simplejwt.readthedocs.io/en/latest/customizing_token_claims.html

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        # Add name to token
        token['name'] = user.get_full_name()
        # You can add other information into the token here
        return token

class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

然后,我更新了我的

urls.py
以使用自定义视图:

path('token/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'),

最后,在我的 Vue.js 应用程序中,我安装了 jwt-decode 包并像这样使用它:

const token = localStorage.getItem('access_token');
const decoded = jwt_decode(token);
console.log(decoded)
// decoded.name contains the user's full name

请注意,我事先将访问令牌存储在本地存储中。


0
投票

如果您使用 Django REST Framework (DRF) 等框架和 JWT 身份验证包(例如 SimpleJWT),那么使用 request.auth.get("FieldName") 确实是一种更干净、更好的方法。

© www.soinside.com 2019 - 2024. All rights reserved.