How does Django create and verify tokens to reset password?

Asked

Viewed 821 times

5

Considering a model to reset password already implemented by Django, in the following views:

  • Django.contrib.auth.password_reset
  • Django.contrib.auth.password_reset_done
  • Django.contrib.auth.password_reset_confirm
  • Django.contrib.auth.password_reset_complete

In view "Django.contrib.auth.password_reset" a token passed as url parameter for the view is generated "Django.contrib.auth.password_reset_confirm".

About this token, I found nothing about it in the Django documentation and also could not understand the source code, however I have the following questions:

  1. How it is generated and verified?
  2. The token is either persisted in the database and linked to the user, or only an id hash is generated ?
  3. Using this method tokens can be generated for other utilities, for example to activate an account?

1 answer

4


Excellent guy question!

Come on, according to django documentation:

There are 4 views for password reset:

# - password_reset envia o email
# - password_reset_done mostra uma mensagem de sucesso para o envio do email
# - password_reset_confirm checa a url e pergunta por uma nova senha
# - password_reset_complete mostra uma mensagem de sucesso para todo o processo

Views password_reset and password_reset_confirm use the same class to generate and check the token. django.contrib.auth.tokens.default_token_generator.

1. How it is generated and verified?

Looking at the documentation link it is possible to notice that Django uses the following class for token generation from django.contrib.auth.tokens.default_token_generator.

Looking for that class in the github project it is possible to verify that the token is generated according to the user and the timestamp.

Removing comments from the code if you have:

def make_token(self, user):
    return self._make_token_with_timestamp(user, self._num_days(self._today()))

def _make_token_with_timestamp(self, user, timestamp):
    ts_b36 = int_to_base36(timestamp)
    hash = salted_hmac(
        self.key_salt,
        self._make_hash_value(user, timestamp),
    ).hexdigest()[::2]
    return "%s-%s" % (ts_b36, hash)

def _make_hash_value(self, user, timestamp):
    login_timestamp = '' if user.last_login is None else user.last_login.replace(microsecond=0, tzinfo=None)
    return (
        six.text_type(user.pk) + user.password +
        six.text_type(login_timestamp) + six.text_type(timestamp)
    )

By checking this code and what’s on github (I won’t include everything because I think it’s unnecessary) we can conclude that the token formed is generated from the timestamp+"-"+hash

Where:

#timestamp = conversao numero de dias desde 01/01/2001 para a base 36.
#hash = user.pk + user.password + user.last_login + timestamp

The fact that the code is used six.text_type is due to the fact that a pattern of str for the Python3 and unicode for the other versions, as shown in the class code itself six.

if PY3:
    string_types = str,
    integer_types = int,
    class_types = type,
    text_type = str
    binary_type = bytes

    MAXSIZE = sys.maxsize
else:
    string_types = basestring,
    integer_types = (int, long)
    class_types = (type, types.ClassType)
    text_type = unicode
    binary_type = str

2. The token is either persisted in the database and linked to the user, or only one id hash is generated ?

As it is possible to verify in the project code, the token is not persisted but generated and confirmed at the time of access. As demonstrated in the first question.

3. Using this method tokens can be generated for other utilities, for example to activate an account?

Yes, you can enjoy the class django.contrib.auth.tokens.default_token_generator to be able to generate and validate the token, but you will have to implement your own views.

  • Thank you very much, I had seen this code on Github but I didn’t understand how it was the validation since it was not persisted a code for comparison, so summarizing and similar to the way it encrypts the password, just uses the same encryption mechanism and compares the keys ?

  • This documentation and version 1.8 , is valid for newer versions ?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.