django - 如何在 user.save() 之后验证并返回访问和刷新 token

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

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

通常,当用户登录时,我使用以下方法 MyTokenObtainPairView ,该方法将访问 token 和刷新 token 以及所有其他内容返回到 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)

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

最佳答案

user.save() 不会创建 token

token = RefreshToken.for_user(obj) 返回str(token.access_token)

这些行创建 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)

关于django - 如何在 user.save() 之后验证并返回访问和刷新 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71081414/

相关文章:

Django:resolve(request.path).app_name不返回应用程序名称

django - 如何使用 django-userena 在注册时将用户分配给组?

python - Django 无法识别 django 管理 url

python - Django 为 WebView 返回带有 TokenAuthentication 的 View

django - 自定义 DjangoRestFramework 可浏览 API

python - django.core.exceptions.ImproperlyConfigured : Field name `id` is not valid for model

python - Django 每个用户 View 缓存

python - Django 中的链式选择 [模块 : django-smart-selects]

python - Django : Message system, 请求

python - Coverage 无法将 'manage.py' 作为 Python 代码运行