Token Authentication for RESTful API: should the token be periodically changed?

后端 未结 10 1303
庸人自扰
庸人自扰 2020-12-02 03:20

I\'m building a RESTful API with Django and django-rest-framework.

As authentication mechanism we have chosen \"Token Authentication\" and I have already implemented

10条回答
  •  情歌与酒
    2020-12-02 03:55

    I've tried @odedfos answer but I had misleading error. Here is the same answer, fixed and with proper imports.

    views.py

    from django.utils import timezone
    from rest_framework import status
    from rest_framework.response import Response
    from rest_framework.authtoken.models import Token
    from rest_framework.authtoken.views import ObtainAuthToken
    
    class ObtainExpiringAuthToken(ObtainAuthToken):
        def post(self, request):
            serializer = self.serializer_class(data=request.DATA)
            if serializer.is_valid():
                token, created =  Token.objects.get_or_create(user=serializer.object['user'])
    
                if not created:
                    # update the created time of the token to keep it valid
                    token.created = datetime.datetime.utcnow().replace(tzinfo=utc)
                    token.save()
    
                return Response({'token': token.key})
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    

    authentication.py

    from datetime import timedelta
    from django.conf import settings
    from django.utils import timezone
    from rest_framework.authentication import TokenAuthentication
    from rest_framework import exceptions
    
    EXPIRE_HOURS = getattr(settings, 'REST_FRAMEWORK_TOKEN_EXPIRE_HOURS', 24)
    
    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')
    
            if token.created < timezone.now() - timedelta(hours=EXPIRE_HOURS):
                raise exceptions.AuthenticationFailed('Token has expired')
    
            return (token.user, token)
    

提交回复
热议问题