Excellent question man!
Come on, as per the 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
The 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 is it generated and verified?
Looking at the documentation link you can see that django uses the following class to generate the token from django.contrib.auth.tokens.default_token_generator
.
Searching for this class in the github project you can check that the token is generated according to the user and the timestamp.
Removing comments from the code if it has:
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)
)
Checking this code and what is in github (I will not include everything because I believe it is unnecessary) we can conclude that the token formed is generated from 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 uses six.text_type
is due to the fact that a str
pattern was set for Python3 and unicode
for other versions, as you can see in the code itself for the six
class.
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. Is the token persisted in the database and bound to the user, or is it only generated a hash of the id?
As you can see in the project code, the token is not persisted but is generated and acknowledged at the time of access. As demonstrated in the first question.
3. Using this method can be generated tokens for other utilities, such as activating an account?
Yes, you can use the django.contrib.auth.tokens.default_token_generator
class to do token generation and validation, but you will need to implement your own views.