Django: How to delete token after it is used?











up vote
1
down vote

favorite












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?










share|improve this question
























  • That's not enough code to understand what you are doing. Where is this code and how is it being used?
    – Daniel Roseman
    Mar 12 at 10:47










  • @DanielRoseman code is updated.
    – Cody
    Mar 12 at 11:00















up vote
1
down vote

favorite












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?










share|improve this question
























  • That's not enough code to understand what you are doing. Where is this code and how is it being used?
    – Daniel Roseman
    Mar 12 at 10:47










  • @DanielRoseman code is updated.
    – Cody
    Mar 12 at 11:00













up vote
1
down vote

favorite









up vote
1
down vote

favorite











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?










share|improve this question















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?







django






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 12 at 10:53

























asked Mar 12 at 10:45









Cody

87311231




87311231












  • That's not enough code to understand what you are doing. Where is this code and how is it being used?
    – Daniel Roseman
    Mar 12 at 10:47










  • @DanielRoseman code is updated.
    – Cody
    Mar 12 at 11:00


















  • That's not enough code to understand what you are doing. Where is this code and how is it being used?
    – Daniel Roseman
    Mar 12 at 10:47










  • @DanielRoseman code is updated.
    – Cody
    Mar 12 at 11:00
















That's not enough code to understand what you are doing. Where is this code and how is it being used?
– Daniel Roseman
Mar 12 at 10:47




That's not enough code to understand what you are doing. Where is this code and how is it being used?
– Daniel Roseman
Mar 12 at 10:47












@DanielRoseman code is updated.
– Cody
Mar 12 at 11:00




@DanielRoseman code is updated.
– Cody
Mar 12 at 11:00












2 Answers
2






active

oldest

votes

















up vote
0
down vote













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(...)






share|improve this answer






























    up vote
    0
    down vote













    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()





    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














       

      draft saved


      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f49233271%2fdjango-how-to-delete-token-after-it-is-used%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      0
      down vote













      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(...)






      share|improve this answer



























        up vote
        0
        down vote













        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(...)






        share|improve this answer

























          up vote
          0
          down vote










          up vote
          0
          down vote









          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(...)






          share|improve this answer














          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(...)







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 12 at 14:11

























          answered Mar 12 at 13:57









          Andrzej Kostański

          10.3k771104




          10.3k771104
























              up vote
              0
              down vote













              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()





              share|improve this answer

























                up vote
                0
                down vote













                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()





                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  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()





                  share|improve this answer












                  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()






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 10 at 17:53









                  Jie Zhou

                  111




                  111






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f49233271%2fdjango-how-to-delete-token-after-it-is-used%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Bressuire

                      Vorschmack

                      Quarantine