1

I have successfully(hopefully) managed to implement a change_password action.

However, after I change the password, the client automatically logsout. (token is probably not valid anymore)

I would like the API Client to remain logged in after a password reset to make other requests with the new token.

Is there an equivalent for update_session_auth_hash(request, self.object) ?

Serializers:

class PasswordSerializer(serializers.Serializer):
    """
    Serializer for password change endpoint.
    """
    old_password = serializers.CharField(required=True)
    new_password = serializers.CharField(required=True)

API View

    @action(methods=['put'], detail=True)
    def change_password(self, request, pk):
        serializer = PasswordSerializer(data=request.data)
        if serializer.is_valid():
            user = get_object_or_404(User, pk=pk)
            if user != request.user:
                return Response({'error': "Cannot change other user's password"},
                                status=status.HTTP_403_FORBIDDEN)
            else:
                if not user.check_password(serializer.data.get('old_password')):
                    return Response({'old_password': ['Wrong password.']},
                                    status=status.HTTP_400_BAD_REQUEST)
                user.set_password(request.POST.get('new_password'))
                user.save()
        else:
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)
        return Response({'details': 'Success'}, status=status.HTTP_200_OK)
Vlad Otrocol
  • 2,952
  • 7
  • 33
  • 55
  • You should really consider your design though. People change passwords because they either lost the old one or think that someone has got hold of their account. That is why the usual design is to automatically logout all sessions of the user on password change. However your design will defeat the second use case as the hacker will still have access even when password has been changed – Ken4scholars Jan 07 '19 at 20:08
  • I want to change the password when editing my profile. Bu I want it as a separate api call from put on user. – Vlad Otrocol Jan 07 '19 at 20:22
  • Password change is usually separate endpoint from user edit for good reasons. Of course you can find your way around this mecahnism, but it is there for good reasons and doing away with them may make your application vulnerable – Ken4scholars Jan 07 '19 at 20:32
  • Let's say I am on a mobile app. I go to my profile and change my password. Type in the old passoword, Type in the new password twice and submit. This will call a change password endpoint. Should I be logged out automatically and be redirected to the login screen in my app? Or should I redirect to my profile with a message, password reset successfully? – Vlad Otrocol Jan 09 '19 at 08:38
  • on web app, after I submit my change password form I use update_session_auth_hash(request, self.object) to keep the user logged in and redirect to homepage or smthing. From what I see this seems standard practice. All I want is to do the same thing on my mobile app, but using the token auth from the rest API instead the session auth from web. – Vlad Otrocol Jan 09 '19 at 08:40
  • 1
    Ok, I get it. You should follow @Noah's answer below then. What it does is delete the current sessions, but returns an auth token to be used for requests immediately without need to make another login request with username and password. So, basically, for the user the transition is seamless. – Ken4scholars Jan 09 '19 at 10:32

1 Answers1

2

You can replaced by a new token after changing password successfully.

token, created =  Token.objects.get_or_create(user=serializer.object['user'])

token.delete()
token.created = Token.objects.create(user=serializer.object['user'])
token.save()
Nouh Belahcen
  • 774
  • 1
  • 11
  • 36