如何在登录过程中生成rest_framework_jwt令牌

how to generate rest_framework_jwt token in the login process

我正在尝试实施 django-rest-framework-jwt 进行身份验证。我做了所有 jwt 教程所说的(添加设置,url 和 curl 测试)。我确实在可浏览的 api.

中使用 127.0.0.1:8000/api/auth/token/ 成功获取了令牌

但我不明白如何在登录过程中生成令牌。我的猜测是在 LoginSerializer 中生成它吗? (或者我误解了这个概念!)

这是我的:

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}

# project/urls.py
url(r'^api/auth/token/', obtain_jwt_token),

登录序列化器和视图:

class UserLoginSerializer(ModelSerializer):
    token = CharField(allow_blank=True, read_only=True)
    class Meta:
        model = User
        fields = ('username', 'password', 'token')

    def validate(self, data):
        username = data.get('username',None)
        password = data['password']

        user = authenticate(username=username, password=password)
        if not user or not user.is_active:
            raise ValidationError("Invalid username/password.")

        # generate jwt token ??
        # data['token'] = generated jwt token??

        return data


class UserLoginAPIView(APIView):
    permission_classes = [AllowAny]
    serializer_class = UserLoginSerializer

    def post(self, request, *args, **kwargs):
        data = request.data
        serializer = UserLoginSerializer(data=data)
        if serializer.is_valid(raise_exception=True):
            new_data = serializer.data
            return Response(new_data, status=HTTP_200_OK)
        return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)

那我该怎么办?

这是我做的。

from rest_framework_jwt.settings import api_settings


class LoginView(APIView):
    '''
    Post call for user login.
    '''

    def post(self, request, format=None):
        serializer = LoginSerializer(data=request.data)

        if serializer.is_valid():

            # Check if user has valid credentials and return user instance else None
            user = authenticate(username=serializer.validated_data['username'],
                                password=serializer.validated_data['password'])

            if user is not None:

                jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
                jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

                payload = jwt_payload_handler(user)
                token = jwt_encode_handler(payload)

                return Response({'msg':'Login successful', 'token': token, 'is_login_success': True}, status=status.HTTP_200_OK)
            else:
                return Response({'msg': 'Credentials are not valid!'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

但你不必这样做,因为你的 127.0.0.1:8000/api/auth/token/ 做的几乎完全一样,除非你想在登录前记录一些东西。

如果您想了解有关 obtain_jwt_token 视图如何工作的更多信息,JSONWebTokenSerializer 会对您有所帮助。