How to Override TokenAuthentication Backend to detect an expiring token

Why would you want to keep your tokens around forever?

You don’t want to give away tokens that last forever when you’re authenticating because what that means for your users is that, if a token is stolen, an attacker will be able to login as long as your user’s token exists in the database. This is why JWT might seem to be “BETTER” than Token Authentication.

Token Auth with expiring tokens is a breeze

You definitely don’t know need to implement JWT in order to get the security of JWT. Token Authentication expiring tokens are a breeze and you’ll see the simplest way to implement them.

Determine how long you want your users to stay authenticated

This ends up being a question between usability, or how often would a user want to login and security. Obviously, you don’t want to keep a user logged in forever otherwise, an attacker could steal a user’s token and stay logged in on your user’s account forever.

On the other hand, it’s nice when you don’t have to continue to log in every time you want to to connect. When was the last time your had to log into Facebook?

A good rule of thumb is 2 weeks to 30 days.

Create a new Setting with that specific length of time

This is an arbitrary naming scheme that you can remember like, TOKEN_EXPIRE_TIME (or similar).

You always want to keep these constants in the setting.py file because you can update functionality in one place and it will automatically update how sections of your code works.

Here’s an example of setting expiring time:

settings.py

import datetime
TOKEN_EXPIRE_TIME=datetime.timedelta(days=30)

Override the TokenAuthentication Class to check validation

Now, you need to override the Token Authentication class so that every time Django REST Framework trying to authenticate you, our TokenAuthentication backend will check to see if your token is valid based on our TOKEN_EXPIRE_TIME setting.

So, here is our new backend. Remember to update your DEFAULT_AUTHENTICATION_CLASSES.

authentication.py

from rest_framework.authentication import TokenAuthentication, get_authorization_header
from rest_framework.exceptions import AuthenticationFailed
from django.conf import settings
import pytz

class ExpiringTokenAuthentication(TokenAuthentication):
    def authenticate_credentials(self, key):
        try:
            token = self.model.objects.get(key=key)
        except self.model.DoesNotExist:
            raise exceptions.AuthenticationFailed('Invalid token')

        if not token.user.is_active:
            raise exceptions.AuthenticationFailed('User inactive or deleted')

        utc_now = datetime.utcnow()
        utc_now = utc_now.replace(tzinfo=pytz.utc)

        if token.created < utc_now - settings.TOKEN_EXPIRE_TIME:
            raise exceptions.AuthenticationFailed('Token has expired')

        return token.user, token

Conclusion

This is an example of how you could override TokenAuthentication backend so that you can detect if your token is expired. The next thing you would need to do is create a new token for your users the next time they login.

Token Authentication can be a very robust authentication method. It’s up to you to figure out the best way to override Token Authentication to suit your needs because Token Authentication doesn’t do everything it should out of the box.

If you want to learn more about how to override Token Authentication so that it’s more robust, more secure and works better, you don’t have to guess any longer. I’m writing an ebook that will teach you these techniques in Token Authentication.

Want to learn more? Click here to learn about my book I’m writing. I’m launching soon! So, get it while it’s hot!