开发组在开发过程当中,都不可避免地遇到了一些困难或问题,但都最终想出办法克服了。咱们认为这样的经验是有必要记录下来的,所以就有了【技术博客】。html
这篇技术博客基于软件工程课程的VisualPytorch之上。本文小部分参考了https://jwt.io/introduction/python
在作绝大部分数据库系统时(网站、小程序),登陆注册确定是一个绕不开的功能。通常来讲传统的解决方案是基于session机制的认证,也就是客户端发送用户名密码给服务器,服务器端验证后建立一个session,把session的id返回客户端,客户端每次请求时带着session的id以此做为验证。git
从个人视角来看主要存在两个问题:github
session通常保存在内存中,固然比较大的应用保存在Redis这类数据库中,经过session_id来作认证增长了访存次数,影响性能。数据库
若是你的应用须要支持经过微信号、QQ号登陆,session_id的方式显然很成问题,毕竟你不可能拿到腾讯的数据库里的内容。django
这里就考虑了使用JWT机制来进行认证。JWT全称是JSON WEB TOKEN,若是使用JWT进行认证,服务器端不须要保存信息,由于JWT将信息加密到了token里。用户只须要每次请求的时候带着token便可,服务器会本身解密。小程序
须要补充的一点是,JWT和session机制并不冲突,若是你的应用对于session有需求,可使用JWT作认证,session作其余需求。后端
若是想比较详细地了解JWT,能够参考RFC7519。服务器
有一个基于Django Restful接口的包能够用微信
pip install djangorestframework-jwt
详细使用方法参照官方文档。
该中间件主要提供了三个接口
#得到token from rest_framework_jwt.views import obtain_jwt_token #刷新token from rest_framework_jwt.views import refresh_jwt_token #验证token from rest_framework_jwt.views import verify_jwt_token
登陆时调用obtain_jwt_token便可。
而对于须要验证用户权限的接口,须要在settings.py中添加
'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ]
随后在接口层中增长须要的权限便可自动利用jwt来验证(不须要调用上文提到的verify_jwt_token),例如
permission_classes = (permissions.IsAuthenticated,)
这个其实和JWT无关,和Django有关,但既然都是一个项目下的,不妨多写一下,以防有需求。
方法重写Django中User的的后端类中的authenticate方法,而且在settings.py中添加
AUTHENTICATION_BACKENDS = [ 'user.utils.UserAuthBackend', # 修改auth认证后端类,这里要写你本身新写的验证类 ]
我重写验证方法的代码以下,仅供参考
from django.contrib.auth.backends import ModelBackend from .models import User from django.db.models import Q class UserAuthBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): # 邮箱或用户名登陆 try: user = User.objects.get(Q(username=username) | Q(email=username)) except User.DoesNotExist: return None else: if user.check_password(password) and self.user_can_authenticate(user): return user
这个中间价的默认设置一个token有效时间为300s,token与其子孙token的过时时间为7天。
也就是说每隔300s都必须刷新当前的token,而隔7天的话刷新也无用必须从新获取。
须要更改设置能够参考官方文档。