Reputation: 2649
In Django, I am generating tokens for account activation. Here is the actual code:
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': default_token_generator.make_token(user),
For instance:
http://localhost:8000/reset/MjQ/4uf-785b6e83f11ac22b6943/
In the above url MjQ
is uid
and 4uf-785b6e83f11ac22b6943
is token
.
The account activation code goes like this:
def activate_account(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = get_user_model().objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if (user is not None and default_token_generator.check_token(user, token)):
user.is_active = True
user.save()
messages.add_message(request, messages.INFO, 'Account activated. Please login.')
return redirect('login')
The problem is once it is used it is still valid. However, Django password reset mechanism (password_reset_confirm()
view) somehow invalidates the token after it is used. How can I do the same?
Upvotes: 3
Views: 1553
Reputation: 31
The token is not stored. It is a hash value based on:
the user's password
the user's last login date
Thus when Django's password reset confirm actually changes the password, the token hash is automatically invalidated.
If you want to manually invalidate the hash, you can do so by either:
generate and store a random password for that user (this may not be what you want if you to retain the user's previous password):
password = User.objects.make_random_password()
user.set_password(password)
or reset the user's last login date to the current timestamp
from django.utils import timezone
user.last_login = timezone.now()
Upvotes: 2
Reputation: 23351
Why taking care of deleting stuff? It is much better to use something what expires automatically after some time.
See django.core.signing.TimestampSigner
https://docs.djangoproject.com/en/2.0/topics/signing/#verifying-timestamped-values
for nice how-to
see this page I will only extend it by wrapping the generated key in base64.urlsafe_b64encode(...)
and then before unsigning base64.urlsafe_b64decode(...)
Upvotes: 0