Skip to content

Instantly share code, notes, and snippets.

@cb109
Last active January 25, 2023 08:42
Show Gist options
  • Save cb109/c81bb35ed3dcfe093d5a5775f31e2ea2 to your computer and use it in GitHub Desktop.
Save cb109/c81bb35ed3dcfe093d5a5775f31e2ea2 to your computer and use it in GitHub Desktop.
Setting up DRF Token authentication with basic expiration
from datetime import timedelta
from django.conf import settings
from django.utils import timezone
from rest_framework.authentication import TokenAuthentication
from rest_framework.authtoken.models import Token
from rest_framework.exceptions import AuthenticationFailed
def is_token_expired(token):
min_age = timezone.now() - timedelta(
seconds=settings.TOKEN_EXPIRED_AFTER_SECONDS)
expired = token.created < min_age
return expired
class ExpiringTokenAuthentication(TokenAuthentication):
"""Same as in DRF, but also handle Token expiration.
An expired Token will be removed and a new Token with a different
key is created that the User can obtain by logging in with his
credentials.
Raise AuthenticationFailed as needed, which translates
to a 401 status code automatically.
https://stackoverflow.com/questions/14567586
"""
def authenticate_credentials(self, key):
try:
token = Token.objects.get(key=key)
except Token.DoesNotExist:
raise AuthenticationFailed("Invalid token")
if not token.user.is_active:
raise AuthenticationFailed("User inactive or deleted")
expired = is_token_expired(token)
if expired:
token.delete()
Token.objects.create(user=token.user)
raise AuthenticationFailed("Token has expired")
return (token.user, token)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'myproject.authentication.ExpiringTokenAuthentication',
)
}
@cb109
Copy link
Author

cb109 commented Jan 25, 2023

@SoundWaveX81 That's indeed shorter, good point. Back then I copied the full method to see how I could extend it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment