10

在 Django 中,超级用户可以根据他们的滚动添加更多用户。我正在使用带有 DRF 的简单 JWT 进行身份验证。但是仅通过查看访问令牌和刷新令牌是不可能检测到用户类型的。

这是我的 settings.py 文件

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
    'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',),


}

网址.py

from django.contrib import admin
from django.urls import path, include
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView


urlpatterns = [

    path('admin/', admin.site.urls),
    path('', include('Manage_Merchants.urls')),

    path('api-auth', include('rest_framework.urls')),
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),


]

当我通过 Postman 访问 127.0.0.1:8000/api/token/ 时,它会询问用户名和密码。当我输入用户名和密码时,它会生成一个刷新和访问令牌。 使用 Postman 使用 DRF 生成 JWT

那么如何识别为超级用户或其他用户创建的超级用户生成的令牌?如何将更多值作为字典与访问和刷新令牌一起传递以识别用户类型?

4

3 回答 3

17

在版本中djangorestframework-simplejwt==4.4.0,它是方法validate而不是to_representation,意思是:

在你的serializer.py你需要覆盖TokenObtainPairSerializer,以便在响应中包含你想要发送的所有数据

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer


class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        # The default result (access/refresh tokens)
        data = super(CustomTokenObtainPairSerializer, self).validate(attrs)
        # Custom data you want to include
        data.update({'user': self.user.username})
        data.update({'id': self.user.id})
        # and everything else you want to send in the response
        return data

现在,您views.py需要覆盖 TokenObtainPairView 以便将其与新的序列化程序配对。

from .serializers import CustomTokenObtainPairSerializer


class CustomTokenObtainPairView(TokenObtainPairView):
    # Replace the serializer with your custom
    serializer_class = CustomTokenObtainPairSerializer

现在将它映射到您的url.py

from rest_framework_simplejwt.views import TokenRefreshView, TokenVerifyView
from . import views

urlpatterns = [
    # This one now has the custom view mapped with the custom serializer that includes the desired data
    path('token/', views.CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('token/verify/', TokenVerifyView.as_view(), name='token_verify')
]

于 2020-02-20T00:49:04.767 回答
8

就像 kumar 说的,你应该重写 TokenObtainPairView。让我更深入地了解它:

在您的核心应用程序views.py 中创建一个新的classView,或者如果您想拥有更简洁的代码,您可以创建一个新应用程序,例如名为jwt_token_patched 并在其中创建一个views.py 文件。现在添加以下代码:

class TokenObtainPairPatchedView(TokenObtainPairView):
    """
    Takes a set of user credentials and returns an access and refresh JSON web
    token pair to prove the authentication of those credentials.
    """
    serializer_class = serializers.TokenObtainPairPatchedSerializer

    token_obtain_pair = TokenObtainPairView.as_view()

现在为序列化程序添加这个:

class TokenObtainPairPatchedSerializer(TokenObtainPairSerializer):
     def to_representation(self, instance):
         r = super(TokenObtainPairPatchedSerializer, self).to_representation(instance)
         r.update({'user': self.user.username})
         return r

当序列化程序以 json 格式返回数据时,将调用方法 to_representation(),因此您可以在其中添加任何您想要的内容。请记住,我只是将用户名放在用户字段值中,您可以在其中添加您想要的用户的任何项目值。

还为此创建一个 url,从现在开始使用该方法获取令牌。如果您愿意,请随时提出任何问题。希望它有用:)

于 2018-11-28T05:38:04.920 回答
1

对于自定义刷新令牌,您可以做的最好的事情是覆盖下面显示的“TokenRefreshSerializer”。但是,如果您想从模型中获取任何字段,我们必须解码令牌以获取用户的 UUID。这可以使用 token_backend 来完成

注意:请确保您使用的是“rest_framework_simplejwt”而不是“djangorestframework-jwt”,因为它已被弃用

from rest_framework_simplejwt.serializers import TokenRefreshSerializer
from rest_framework_simplejwt.state import token_backend

class CustomTokenRefreshSerializer(TokenRefreshSerializer):
    def validate(self, attrs):
        data = super(CustomTokenRefreshSerializer, self).validate(attrs)
        decoded_payload = token_backend.decode(data['access'], verify=True)
        user_uid=decoded_payload['user_id']
        # add filter query
        data.update({'custom_field': 'custom_data')})
        return data

然后使用继承“TokenRefreshView”的“CustomTokenRefreshView”如下所示的序列化程序

from rest_framework_simplejwt.views import TokenRefreshView
class CustomTokenRefreshView(TokenRefreshView):
    """
    Custom Refresh token View
    """
    serializer_class = CustomTokenRefreshSerializer

并将其添加到网址中

path('api/token/refresh/', CustomTokenRefreshView.as_view(), name='token_refresh'),
于 2020-12-28T12:06:52.143 回答