Last active
January 25, 2023 08:42
-
-
Save cb109/c81bb35ed3dcfe093d5a5775f31e2ea2 to your computer and use it in GitHub Desktop.
Setting up DRF Token authentication with basic expiration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
REST_FRAMEWORK = { | |
'DEFAULT_AUTHENTICATION_CLASSES': ( | |
'myproject.authentication.ExpiringTokenAuthentication', | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@SoundWaveX81 That's indeed shorter, good point. Back then I copied the full method to see how I could extend it.