【问题标题】:How to validate and return access and refresh tokens after user.save()如何在 user.save() 之后验证并返回访问和刷新令牌
【发布时间】:2022-02-12 18:19:09
【问题描述】:

我正在验证用户 OTP 以更改密码,更改密码后我无法使用 JWT 创建访问和刷新令牌,

通常当用户登录时,我使用以下方法 MyTokenObtainPairView 将访问和刷新令牌以及所有其他内容返回给 UserSerializerWithToken

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)

        serializer = UserSerializerWithToken(self.user).data
        for k, v in serializer.items():
            data[k] = v

        return data


class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

我复制了类似的方法在 set_password 和 user.save() 之后返回 UserSerializerWithToken

UserSerializerWithToken 是

class UserSerializerWithToken(UserSerializer):
    token = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CustomUser
        fields = ['id',
                  'isAdmin',
                  'token']

    def get_token(self, obj):
        token = RefreshToken.for_user(obj)
        return str(token.access_token)

而有问题的功能是

@api_view(['PUT'])
def reset_password(request):
    data = request.data
    email = data['email']
    otp_to_verify = data['otp']
    new_password = data['password']
    user = CustomUser.objects.get(email=email)
    serializer = UserSerializerWithToken(user, many=False)
    if CustomUser.objects.filter(email=email).exists():
        if otp_to_verify == user.otp:
            if new_password != '':
                user.set_password(new_password)
                user.save() # here password gets changed 
                return Response(serializer.data) # 
            else:
                message = {
                'detail': 'Password cant be empty'}
                return Response(message, status=status.HTTP_400_BAD_REQUEST)
    else:
        message = {
            'detail': 'Something went wrong'}
        return Response(message, status=status.HTTP_400_BAD_REQUEST)

我收到令牌但无法访问并刷新令牌以使用它下次登录。我假设 user.save() 不在这里创建刷新和访问令牌。任何人都可以确定为什么会发生这种情况以及如何解决这个问题

【问题讨论】:

    标签: django django-rest-framework django-views jwt django-validation


    【解决方案1】:

    user.save() 不创建令牌

    token = RefreshToken.for_user(obj) return str(token.access_token)

    这些行创建了令牌。

    在我看来,这里不需要序列化器。

    @api_view(['PUT'])
    def reset_password(request):
        data = request.data
        email = data['email']
        otp_to_verify = data['otp']
        new_password = data['password']
        user = CustomUser.objects.get(email=email)
        if CustomUser.objects.filter(email=email).exists():
            otp_to_verify == user.otp
            if new_password != '':
                user.set_password(new_password)
                user.save() # here password gets changed 
                token = RefreshToken.for_user(user)
                response = { "refresh_token": str(token),
                             "access_token": str(token.access_token)
                           }
                return Response(response)
            else:
                message = {
                    'detail': 'Password cant be empty'}
                return Response(message, status=status.HTTP_400_BAD_REQUEST)
        else:
            message = {
                'detail': 'Something went wrong'}
            return Response(message, status=status.HTTP_400_BAD_REQUEST)
    

    【讨论】:

    • 感谢 Arun,它正在生成令牌,但没有使用新的刷新和访问令牌更新用户,您可以更新此功能以便它也可以使用令牌更新用户
    • 用新令牌更新用户是什么意思?您的前端应用程序必须在其会话中更新令牌。
    • 你能让它工作吗?
    • 是的,前端有问题
    • 并且保存后不需要生成token
    猜你喜欢
    • 2021-01-25
    • 1970-01-01
    • 2020-02-16
    • 2020-11-09
    • 2019-11-29
    • 2021-11-21
    • 2020-07-12
    • 1970-01-01
    • 2021-09-17
    相关资源
    最近更新 更多