在Django rest framework中使用simple JWT获取用户详细信息

10
我正在使用React和Django rest framework进行一个项目。我使用Django rest framework simple JWT进行认证。现在,我想在用户登录后在导航栏中显示用户名。那么,在simple JWT中是否有一种方法可以通过认证后生成的访问令牌返回用户详细信息,就像当提供访问令牌时Djoser返回用户凭据一样?对不起,如果这个问题很傻,但我无法在任何地方找到解决方案。

https://django-rest-framework-simplejwt.readthedocs.io/en/latest/customizing_token_claims.html - Aprimus
可能是我漏看了。非常感谢你! - srijan sankrit
嘿,@Aprimus,那个页面只是介绍如何自定义令牌。我的问题是,simple JWT 中是否有预构建的函数可帮助从令牌中提取声明,还是我必须自己完成? - srijan sankrit
4个回答

5

如果您想获取令牌所有者的信息,可以在请求中查阅。

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

3
关于后端,基本上我使用这个库。
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只是一个示例。你应该将它作为参数传递。


1
access_token_str 过期时,这会怎么样? - cch
我在文件中写的字符串 access_token_str 只是一个示例。你应该将它作为参数传递。 - quine9997

1
如果你想以这种格式自定义返回的数据:
{
    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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接