Bidhan Majhi
Bidhan Majhi

Reputation: 1370

Expire the user activation link and remove from database in django

I have an user signup, where the user's account is activated after link with a token send to their email address is clicked. I want to expire the link and delete their data from the database if the specific link is not clicked within 24 hours.

I have read it in one place, that the link is expired after 48 hours, is that correct?

Here is my question -

How can I automatically remove those users who do not click on the activation link with in 24 hours?

(So far I can do that by going to admin panel and by checking email is confirmed or not)

Here is my activate function,

def activate(request, uidb64, token):
    try:
       uid = force_text(urlsafe_base64_decode(uidb64))
       user = User.objects.get(pk=uid)
    except (TypeError, ValueError, OverflowError, ObjectDoesNotExist):
       user = None

    if user is not None and account_activation_token.check_token(user, token):
       user.is_active = True
       user.email_confirmed = True
       user.save()
       login(request, user)
       return redirect('home')
    else:
       return render(request, 'user/account_activation_invalid.html')

This is my tokens.py to create token,

from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six

class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
   def _make_hash_value(self, user, timestamp):
       return (
           six.text_type(user.pk) + 
           six.text_type(timestamp) + 
           six.text_type(user.email_confirmed)
           )

 account_activation_token = AccountActivationTokenGenerator()

What should I change to achieve that?

Upvotes: 4

Views: 4452

Answers (1)

xyres
xyres

Reputation: 21844

The default expiration time of the token is 3 days (72 hours).

You don't need to save the token in database. The token already contains the timestamp of creation time. So all you need to do is override the check_token method in your custom class and check if the timestamp is 24 hours old or not.

Most of the code can be copied verbatim from the the original method. See the source code on github.

All you have to do is change line 49

Sample code:

class AccountActivationTokenGenerator(...):
    ...
    def check_token(self, user, token):

        ...
        if (self._num_days(self._today()) - ts) > 1: # 1 day = 24 hours
            return False

        ...

UPDATE:

To delete unverified users after 24 hours, you can create a cron job which runs every 24 hours and checks your database for unverified users and deletes them if they are more than 24 hours old.

Here's an answer which gives an outline of the process: Django - Set Up A Scheduled Job?. For creating a cron job, see your operating system's documentation.

Another method of adding cron jobs is by using django apps such as django-cron and django-crontab. They are specifically created for making this task easier, but the general principle stays the same as described in the linked answer.

Upvotes: 5

Related Questions