问题描述
最近在工作中遇到这样一个需求,需要对每次后端的请求拦截进行权限验证,若每一次都是对token认证的话,请求认证服务器的次数太多,请求等待的时间也太长,同时也增加了认证服务器的负载。
想法
Django开启了Session的middleware之后,request中会附带一个sessionStorage,其是一个类字典的对象,可以在第一次token认证通过后,把信息附带到该对象中,之后请求只要检查该对象来进行认证。
其本质是利用HTTP服务端的session功能来进行缓存。
具体实现(仅供参考,实际根据业务逻辑变更)
在drf的settings中
REST_FRAMEWORK = {
...,
'DEFAULT_AUTHENTICATION_CLASSES': (
'yourPackage.SessionAuthentication',
'yourPackage.TokenCheck',
),
}
加入自定义的权限验证类,这里session验证一定要放在Token验证之前,这样只有在session验证不通过时才会走Token验证
自定义SessionAuthentication类
class SessionAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
# if the user has logined and not expired, request must have the 'id' in the session
try:
#id just for example
id = request.session['id']
except KeyError:
# can't find user, not passed, need to check token
return None
user = User.objects.get(id=id)
permissions = get_permissions() # 自定义获取权限函数
return (user, permissions)
自定义TokenCheck
class TokenCheck(authentication.BaseAuthentication):
def authenticate(self, request):
# decode token
token = get_token(request)
decoded_token = decode_token(token)
id = decoded_token.get('id')
...
permissions = get_permissions(id)
request.session['id'] = id
request.session['token'] = token
request.session.set_expiry(SESSION_EXIRY_TIME)
return (user, permissions)