drf-双token认证
-
simpleui 集成监控大屏
从gitee上找到开源的前端页面---》集成到项目中即可
网址:https://gitee.com/lvyeyou/DaShuJuZhiDaPingZhanShi?_from=gitee_search
本质就是前后端混合的项目
-
restframework-jwt执行流程分析
签发的token有过期时间,可以直接在seteings.py配置
JWT_AUTH = { 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), } # 过期时间7天
双token认证
当用户正在app或者应用中操作 token突然过期,此时用户不得不返回登陆界面,重新进行一次登录,这种体验性不好,于是引入双token校验机制
使用:
首次登陆时服务端返回两个token ,accessToken和refreshToken,accessToken过期时间比较短,refreshToken时间较长,且每次使用后会刷新,每次刷新后的refreshToken都是不同
流程:
1.登录操作,在后台服务器验证账号密码成功之后返回2个token:accessToken和refreshToken。
2.在进行服务器请求的时候,先将Token发送验证,如果accessToken有效,则正常返回请求结果;如果accessToken无效,则验证refreshToken。
3.此时如果refreshToken有效则返回请求结果和新的accessToken和新的refreshToken。如果refreshToken无效,则提示用户进行重新登陆操作
# django中顶格写的代码,都会执行 # 签发流程--》本质就是登录接口---》【校验用户是否正确,如果正确签发token】写到了序列化类中,如果不正确返回错误 -obtain_jwt_token:核心代码--ObtainJSONWebToken.as_view() -ObtainJSONWebToken 视图类,实现了登录功能 class ObtainJSONWebToken(JSONWebTokenAPIView): serializer_class = JSONWebTokenSerializer -父类ObtainJSONWebToken class JSONWebTokenAPIView(APIView): # 局部禁用掉权限和认证 permission_classes = () authentication_classes = () def get_serializer_context(self): return { 'request': self.request, 'view': self, } def get_serializer_class(self): return self.serializer_class def get_serializer(self, *args, **kwargs): serializer_class = self.get_serializer_class() kwargs['context'] = self.get_serializer_context() return serializer_class(*args, **kwargs) def post(self, request, *args, **kwargs): # JSONWebTokenSerializer实例化得到一个序列号类的对象,传入前端传的只 serializer = self.get_serializer(data=request.data) if serializer.is_valid(): # 校验前端传入的数据是否合法: #1 字段自己的规则 2 局部钩子 3 全局钩子(序列化类的validate方法) # 获取当前登录用户和签发token是在序列化类中完成的 # 从序列化类对象中取出了当前登录用户 user = serializer.object.get('user') or request.user # # 从序列化类对象中取出了token token = serializer.object.get('token') # 自定义过 response_data = jwt_response_payload_handler(token, user, request) response = Response(response_data) return response return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) -序列化类:JSONWebTokenSerializer class JSONWebTokenSerializer(Serializer): def validate(self, attrs): credentials = { 'username': attrs.get('username'), 'password': attrs.get('password') } if all(credentials.values()): # auth的校验用户名和密码是否正确 user = authenticate(**credentials) if user: # 通过用户获得payload:{} payload = jwt_payload_handler(user) return { 'token': jwt_encode_handler(payload), 'user': user } else: # 根据用户名和密码查不到用户 raise serializers.ValidationError(msg) else: # 用户名和密码不传,传多了都不行 raise serializers.ValidationError(msg) # 认证 -认证类;JSONWebTokenAuthentication class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication): def get_jwt_value(self, request): # get_authorization_header(request)根据请求头中HTTP_AUTHORIZATION,取出token # jwt adsfasdfasdfad # auth=['jwt','真正的token'] auth = get_authorization_header(request).split() auth_header_prefix = api_settings.JWT_AUTH_HEADER_PREFIX.lower() if not auth: if api_settings.JWT_AUTH_COOKIE: return request.COOKIES.get(api_settings.JWT_AUTH_COOKIE) return None if smart_text(auth[0].lower()) != auth_header_prefix: return None if len(auth) == 1: msg = _('Invalid Authorization header. No credentials provided.') raise exceptions.AuthenticationFailed(msg) elif len(auth) > 2: msg = _('Invalid Authorization header. Credentials string ' 'should not contain spaces.') raise exceptions.AuthenticationFailed(msg) return auth[1] -父类中:BaseJSONWebTokenAuthentication---》authenticate class BaseJSONWebTokenAuthentication(BaseAuthentication): def authenticate(self, request): # jwt_value前端传入的token jwt_value = self.get_jwt_value(request) # 前端没有传入token,return None,没有带token,认证类也能过,所有咱们才加权限类 if jwt_value is None: return None try: payload = jwt_decode_handler(jwt_value) # 验证token,token合法,返回payload except jwt.ExpiredSignature: msg = _('Signature has expired.') raise exceptions.AuthenticationFailed(msg) except jwt.DecodeError: msg = _('Error decoding signature.') raise exceptions.AuthenticationFailed(msg) except jwt.InvalidTokenError: raise exceptions.AuthenticationFailed() user = self.authenticate_credentials(payload) # 通过payload得到当前登录用户 return (user, jwt_value) # 后期的request.user就是当前登录用户 # 它这个认证类:只要带了token,request.user就有只,如果没带token,不管了,继续往后走
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)