1

I am creating an api using Django Rest Framework, when user signs up (registers) for an account, the user receives a verification email, with a verification link, once clicked the account should be verified. I got the email sending part working and configured.

My question is: How to have the link in the verify-email endpoint activate account when user clicks on it (decode payload) ? I cannot seem to find what I am looking for over the internet, I browsed the DRF documentation, but could not find it.

I am using Django Token Authentication for authentication, that ships with Django rest.

Your inputs are much appreciated.

Thank you.

2 Answers 2

6

First, generate confirmation_token:

from django.contrib.auth.tokens import default_token_generator

confirmation_token = default_token_generator.make_token(user)

Then add this confirmation_token and also user_id to the activation link that will be displayed in the email:

actiavation_link = f'{activate_link_url}?user_id={user.id}&confirmation_token={confirmation_token}'

And finally, you should have this activate view/action to be called when a user navigates by actiavation_link generated above:

@action(detail=False, permission_classes=[AllowAny], methods=['get'])
def activate(self, request, pk=None):
    user_id = request.query_params.get('user_id', '')
    confirmation_token = request.query_params.get('confirmation_token', '')
    try:
        user = self.get_queryset().get(pk=user_id)
    except(TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    if user is None:
        return Response('User not found', status=status.HTTP_400_BAD_REQUEST)
    if not default_token_generator.check_token(user, confirmation_token):
        return Response('Token is invalid or expired. Please request another confirmation email by signing in.', status=status.HTTP_400_BAD_REQUEST)
    user.is_active = True
    user.save()
    return Response('Email successfully confirmed')
Sign up to request clarification or add additional context in comments.

2 Comments

how can you validate that the send link hasn't been used before?
Maybe you have solved it already, but one possible solution would be to place a check if the user has already been verified or not! e.g. if (!user.is_active) then execute the verification code else the user is already verified.
1

I would add this to the accepted answer from GProst

if user.is_email_verified:
    return Response('Email has already been verified.', status=status.HTTP_400_BAD_REQUEST)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.