Search code examples
djangoauthenticationdjango-rest-frameworkdjango-authenticationdjango-rest-auth

Signup email validation using Django rest framework


I am creating a user by sending a POST request through an android app with the request containing a username, password, and email-id. Now in my app, there are two kinds of users i.e. Teachers and Students. Now for distinguishing between teachers and students during signup I want to send a verification email to the teacher comprising of a randomly generated token. Now I want the teacher to enter this token during the signup to verify that actually, a teacher is signing up and not some mischievous student who just wants to mess up with everyone. I am able to send email containing a token but cannot understand that how will I verify it when the teacher enters the token on the app while signing up, matches with the token sent to the email-id.

Below is the code of my serializer used to send the email containing a token

class UserSerializer(serializers.ModelSerializer):
    token = serializers.CharField(max_length=100, null=True, blank=True)

    class Meta:
        model = User
        fields = ('id', 'username', 'password', 'email', 'token')

    def create(self, validated_data):
        user = User(username=validated_data['username'], 
        email=validated_data['email'])
        user.set_password(validated_data['password'])
        user.save()

        subject = "Email verification for django"
        message = account_activation_token.make_token(user)
        send_mail(subject, message, settings.EMAIL_HOST_USER, 
        [user.email])
        return user

As you peeps can see, in the above code I am generating a random token and sending the email when I get a POST request for creating a new user. Now my user will enter the token from the email in the app and send a POST request. Now I want to check whether the token entered by the user is same as the token generated above in the code so that I can verify the user and proceed with the signup form.

PS: My User model doesn't contain a token field as I am using the inbuilt user model provided by Django and connecting it to the Teacher model using a One-To-One-Field

PPS: Is there any other way that I can use to implement the above functionality?


Solution

  • You need to save the token on your side (database) to match it with the one the teacher inputs into your form. So make a model first.

    class Token(models.Model):
        user = models.OneToOneField(User, on_delete=models.CASCADE)
        token = models.CharField(max_length=255)
    

    The line that generates the token comes AFTER the user is created, so you can just use the user instance and save the token on to the model that you just created:

    def create(self, validated_data):
        ...
        message = account_activation_token.make_token(user)
        Token.objects.create(user=user, token=message)
        send_mail(subject, message, settings.EMAIL_HOST_USER,
        ...
    

    Next you use the following code in your view to check if the user have inputed the correct token:

    ...
    token_obj = Token.objects.get(user=user)
    user_token = token_obj.token
    if form.data['token'] == user_token:
        # code to accept the user
        token_obj.delete() # this deletes the row since you will not use it anymore
    else:
        # code to reject the user
    

    Note: Please don't copy paste these codes. Adjust accordingly.