Json web token (JWT),是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准(RFC 7519).该 token 被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。JWT 的声明通常被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也能够增长一些额外的其它业务逻辑所必须的声明信息,该 token 也可直接被用于认证,也可被加密。python
HTTP 是一个无状态的应用层协议。web
比如咱们在淘宝上网购:redis
然而,由于 HTTP 是无状态的,咱们在下单购买的时候,服务器此时已经不记得咱们的身份信息了,须要从新进行身份认证。算法
传统的登陆校验采用的是 cookie-seession 方式,它的流程通常以下:django
传统模式的缺点是可扩展性差。对于单机操做影响不大,但若是是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都可以读取 session,而 session 通常是采用文件的方式存储,这会带来文件同步问题和文件读取问题。即使将 session 放入到 redis 中,也没法避免高并发数据的读取问题。json
JWT 采用的是 token 令牌的方式进行校验:后端
这样作的优势在于:api
一个 JWT 字符串包括如下三个部分:跨域
头部(header)缓存
标识用于生成签名的算法,例如:
{ ‘typ‘: ‘JWT‘, ‘alg‘: ‘HS256‘ }
typ 表示 token 的类型,默认为 JWT,通常不改动。
alg 表示加密算法,默认 HMAC SHA256。
载荷(payload)
签证(signature)
咱们的项目后端是基于 Django 进行开发的。
通常而言是在 restful 的接口中使用 JWT token,相关的 Django 库是 djangorestframework
和 djangorestframework-jwt
。
首先须要在 settings
中设置 DEFAULT_AUTHENTICATION_CLASSES
来进行用户认证:
REST_FRAMEWORK = { 'DEFAULT_SCHEMA_CLASS': ( 'rest_framework.schemas.coreapi.AutoSchema' ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.BasicAuthentication', ) }
接着设置 JWT_AUTH 来进行 token 的刷新:
JWT_AUTH = { 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), 'JWT_ALLOW_REFRESH': True, 'JWT_AUTH_HEADER_PREFIX': 'JWT', }
在用户登陆时,生成 token:
serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = self.perform_create(serializer) re_dict = serializer.data payload = jwt_payload_handler(user) re_dict['token'] = jwt_encode_handler(payload) re_dict['username'] = user.username headers = self.get_success_headers(serializer.data) return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers)
在 urls
中注册路由:
urlpatterns = [ path('login/', obtain_jwt_token), path('refresh/', refresh_jwt_token), path('verify/', verify_jwt_token), ]