Cody
Cody

Reputation: 2649

Django: How to delete token after it is used?

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

Answers (2)

Jie Zhou
Jie Zhou

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

andilabs
andilabs

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

Related Questions