Search code examples
django-rest-frameworkdjango-rest-framework-simplejwtdjoser

How does Djoser account verification system really works under the hood?


So I'm currently in an attempt to make my own account verification system and I'm using some parts of Djoser as a reference. let me try to walk you to my question

Let's say you're to make a new account in Djoser app

  1. you put in the information of your soon to be made account including email

  2. submit the form to the backend

  3. get an email to the whatever email account you put in earlier to verify your account

  4. click the link in your email

  5. get to the verify account page

now in this page there's a button to submit a UID and a token and both of those information lies in the URL.

My question is:

  1. What are those tokens? is it JWT?
  2. How do they work?
  3. How can I implement that in my own projects without djoser?

Solution

  • The answers to your questions are immersed in the own code of djoser. You can check djoser.email file and in the classes there, they are few methods get_context_data().

    def get_context_data(self):
        context = super().get_context_data()
        user = context.get("user")
        context["uid"] = utils.encode_uid(user.pk)
        context["token"] = default_token_generator.make_token(user)
        context["url"] = settings.ACTIVATION_URL.format(**context)
        return context
    

    So get the context in the class where is instance, and in this context add the 'uid' (this is basically str(pk) and coded in base64, check encode_uid()), the 'token' (just a random string created with a Django function from your Secret key; you can change the algorithm of that function and the duration of this token with PASSWORD_RESET_TIMEOUT setting) to use temporary links, and finally the URL according the action which is performed (in this case the email activation).

    Other point to consider is in each of this classes has template assigned and you can override it.

    Now, in the views, specifically in UserViewSet and its actions perform_create(), perform_update() and resend_activation(), if the Djoser setting SEND_ACTIVATION_EMAIL is True, call to ActivationEmail to send an email to the user address.

     def perform_create(self, serializer):
            user = serializer.save()
            signals.user_registered.send(
                sender=self.__class__, user=user, request=self.request
            )
    
            context = {"user": user}
            to = [get_user_email(user)]
            if settings.SEND_ACTIVATION_EMAIL:
                settings.EMAIL.activation(self.request, context).send(to)
            ...
    

    The email is sent and when a user click the link, whether the token is still valid and uid match (djoser.UidAndTokenSerializer), the action activation() of the same View is executed. Change the user flag 'is_active' to True and it may sent another email to confirm the activation.

    If you want code your own version, as you can see, you only have to create a random token, generate some uid to identify the user in the way that you prefer. Code a pair of views that send emails with templates that permit the activation.