zoukankan      html  css  js  c++  java
  • Django restframework Token拥有不过期的认证

    REST框架中的Token认证不像Session认证一样,它是没有办法设置过期时间的,但是有时我们需要对Token做过期验证,比如说用户在A设备登陆之后获取一个Token,如果用户在没有清空浏览器缓存的情况下,Token将一直保存在缓存中,一周后在访问依旧有效,但我们并不希望这样,我们觉得Token认证应该和Session一样都有过期时间,过期之后作废。

    1. 首先,看下TokenAuthentication模块的源码如下:

       class TokenAuthentication(BaseAuthentication):
           keyword = 'Token'
           model = None
       
           def get_model(self):
               if self.model is not None:
                   return self.model
               from rest_framework.authtoken.models import Token
               return Token
       
           def authenticate(self, request):
               auth = get_authorization_header(request).split()
       
               if not auth or auth[0].lower() != self.keyword.lower().encode():
                   return None
       
               if len(auth) == 1:
                   msg = _('Invalid token header. No credentials provided.')
                   raise exceptions.AuthenticationFailed(msg)
               elif len(auth) > 2:
                   msg = _('Invalid token header. Token string should not contain spaces.')
                   raise exceptions.AuthenticationFailed(msg)
       
               try:
                   token = auth[1].decode()
               except UnicodeError:
                   msg = _('Invalid token header. Token string should not contain invalid characters.')
                   raise exceptions.AuthenticationFailed(msg)
       
               return self.authenticate_credentials(token)
       
           def authenticate_credentials(self, key):    # key=前端在请求头传过来的Token
               model = self.get_model()     # 获取Token模块
               try:
                   token = model.objects.select_related('user').get(key=key)   # 通过key获取Token
               except model.DoesNotExist:
                   raise exceptions.AuthenticationFailed(_('Invalid token.'))   # 如果没有就报错
       
               if not token.user.is_active:
                   raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))  # 如果用户没有激活也报错
       
               return (token.user, token)
       
           def authenticate_header(self, request):
               return self.keyword  # 然后把Token和登录的用户返回给View
      

    上面有注解的地方是关键。 过期验证,就相当于多加一个判断,只要继承该类,然后重写authenticate_credentials方法即可。以下是我实现的例子,以expiringTokenAuthentication.py保存。

    from rest_framework.authentication import TokenAuthentication
    from django.utils.translation import ugettext_lazy as _
    from rest_framework import exceptions
    from django.utils import timezone
    from datetime import timedelta
    from django.conf import settings
    class ExpiringTokenAuthentication(TokenAuthentication):
        def authenticate_credentials(self, key):
            model = self.get_model()
            try:
                token = model.objects.select_related('user').get(key=key)
            except model.DoesNotExist:
                raise exceptions.AuthenticationFailed(_('Invalid token.'))
            if not token.user.is_active:
                raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
    		
    		if timezone.now() > (token.created + timedelta(DAYS)):  # 重点就在这句了,这里做了一个Token过期的验证,如果当前的时间大于Token创建时间+DAYS天,那么久返回Token已经过期
            raise exceptions.AuthenticationFailed(_('Token has expired'))
        return (token.user, token)
    

    以此类推, 要对token进行类似的判断,都可以按上面的代码进行仿写。

  • 相关阅读:
    支持高速局域网文件传输的企业云盘(速度可达20M)
    高版本Sqlserver数据库还原到低版本数据库的实现方式
    sqlserver没有采用默认实例时 通过ip进行链接
    AM8互联设置方法
    蛮好用的Gungho重点工作督查督办跟踪管理系统
    AM8后台历史数据手工清理方法
    AM8不能下任何载附件及所有聊天记录无法登记
    【OI】时间复杂度
    【OI】矩阵快速幂
    【Ubuntu】奇怪的无法启动
  • 原文地址:https://www.cnblogs.com/brad1994/p/6691106.html
Copyright © 2011-2022 走看看