簡體   English   中英

使用 Django Rest 框架時,如何在 SimpleJWT 自定義令牌中返回 401 響應?

[英]How do I return a 401 response in a SimpleJWT Custom Token when using the Django Rest Framework?

如果未啟用用戶,我想返回 401 消息。 當我嘗試返回響應而不是令牌時,它不起作用,我理解這是因為序列化程序需要令牌。 如果未啟用用戶,如何自定義它以發送 401 響應?

我的自定義令牌類如下:

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework import status
from rest_framework.response import Response

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        if user.is_enabled:
            token = super().get_token(user)
            # Add custom claims
            token['name'] = user.name
            token['gender'] = user.gender

            return token
        else:
            return Response({'detail':'Account not enabled'}, status=status.HTTP_401_UNAUTHORIZED)

class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

URL 根如下所示:

re_path(r'^authenticate/',CustomTokenObtainPairView.as_view(), name='authenticate'),

如果用戶未啟用,您可以從 get_token 返回一些符號,如 Python 中的 None,然后如果 get_token 的值為 None,則覆蓋 CustomTokenObtainPairView 的 get 方法以返回 401。

編輯:找到了一種更好的方法,將 is_enabled 的檢查移至來自序列化程序的發布請求。 下面是代碼。

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        # Add custom claims
        token['name'] = user.name
        token['gender'] = user.gender

        return token

from rest_framework.permissions import IsAuthenticated

class CustomTokenObtainPairView(TokenObtainPairView):
    permission_classes = [IsAuthenticated]
    serializer_class = CustomTokenObtainPairSerializer
    
    def post(self, request, *args, **kwargs):
        is self.request.user.is_enabled:
            return super().post(request, *args, **kwargs)
        else:
            return Response({'detail':'Account not enabled'}, status=status.HTTP_401_UNAUTHORIZED)

你可以做這樣的東西

from rest_framework import status, serializers
from rest_framework.response import Response
from rest_framework.views import APIView

from rest_framework_simplejwt.tokens import RefreshToken


class LoginUserSerializer(serializers.Serializer):
    email = serializers.EmailField()
    password = serializers.CharField(write_only=True, min_length=5)


class LoginUserApi(APIView):

    def post(self, request):
        serializer = LoginUserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        user = authenticate(email=request.data['email'], password=request.data['password'])
        if not user:
            return Response({'detail':'Incorrect email or password'}, status=status.HTTP_400_BAD_REQUEST)
        elif not user.is_enabled:
            return Response({'detail':'Account not enabled'}, status=status.HTTP_401_UNAUTHORIZED)

        # Generate Token
        refresh = RefreshToken.for_user(user)
        data = {}
        data['name'], data['gender'] = user.name, user.gender
        data['refresh'], data['access'] = str(refresh), str(refresh.access_token)    

        return Response(data, status=status.HTTP_200_OK)

來自文檔的參考

這對我有用,它是一個簡單的解決方案,並為我提供了我需要的結果,這就是我將其發布為答案的原因。

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework import status
from rest_framework.response import Response
from rest_framework_simplejwt.exceptions import InvalidToken

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        if user.is_enabled:
            token = super().get_token(user)
            # Add custom claims
            token['name'] = user.name
            token['gender'] = user.gender
            return token
        else:
            raise InvalidToken("User is not enabled.")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM