jpadilla / django-rest-framework-jwt

JSON Web Token Authentication support for Django REST Framework
http://jpadilla.github.io/django-rest-framework-jwt/
MIT License
3.19k stars 649 forks source link

Invalid signature error second time that I try to change the email in DRF #355

Open ekaitzht opened 7 years ago

ekaitzht commented 7 years ago

I have created a endpoint in Django Rest Framework to change the email, the payload is like this:

PUT /change_email

{
  "user_id": 11,
  "new_email": "user@myemail.com",
  "current_password": "mypassword"
}

If I try to change the email it's working perfect but the second time that I try to make any REST request I get the a 401 error:

{"content":{"detail":"Invalid signature."}}

Serializer:

class ChangeEmailSerializer(serializers.Serializer):
    user_id = serializers.IntegerField(required=True)
    new_email = serializers.CharField(required=True)
    current_password = serializers.CharField(required=True)

View:

class ChangeEmailView(APIView):
    renderer_classes = (CustomJSONRenderer,)
    serializer_class = api_serializers.ChangeEmailSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def put(self, request, format=None):
        serializer = self.serializer_class(data=request.data)

        user_id = request.data['user_id']
        new_email = request.data['new_email']
        current_password = request.data['current_password']

        user = User.objects.get(id=user_id)

        if serializer.is_valid():
            if not user.check_password(current_password):
                return Response({'Wrong password'}, status=status.HTTP_400_BAD_REQUEST)
            else:
                user.email = new_email
                user.username = new_email
                user.save()
                return Response({serializer.data}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Edit:

If I don't update the username I don't get this problem.

skeezus commented 6 years ago

Make sure you're updating in the database Django uses for auth (should be auth_user)

Alex3917 commented 6 years ago

In between tests, you need to do user.refresh_from_db(). There is basically a bug in DRF that necessitates this workaround.