什么是JWTweb
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。JWT的声明通常被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也能够增长一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。算法
起源浏览器
提及JWT,咱们应该来谈一谈基于token的认证和传统的session认证的区别。安全
传统的session认证服务器
咱们知道,http协议自己是一种无状态的协议,而这就意味着若是用户向咱们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,由于根据http协议,咱们并不能知道是哪一个用户发出的请求,因此为了让咱们的应用能识别是哪一个用户发出的请求,咱们只能在服务器存储一份用户登陆的信息,这份登陆信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给咱们的应用,这样咱们的应用就能识别请求来自哪一个用户了,这就是传统的基于session认证。cookie
可是这种基于session的认证使应用自己很可贵到扩展,随着不一样客户端用户的增长,独立的服务器已没法承载更多的用户,而这时候基于session认证应用的问题就会暴露出来.网络
基于session认证所显露的问题session
Session: 每一个用户通过咱们的应用认证以后,咱们的应用都要在服务端作一次记录,以方便用户下次请求的鉴别,一般而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。app
扩展性: 用户认证以后,服务端作认证记录,若是认证的记录被保存在内存中的话,这意味着用户下次请求还必需要请求在这台服务器上,这样才能拿到受权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。负载均衡
CSRF: 由于是基于cookie来进行用户识别的, cookie若是被截获,用户就会很容易受到跨站请求伪造的攻击。
基于token的鉴权机制
基于token的鉴权机制相似于http协议也是无状态的,它不须要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不须要去考虑用户在哪一台服务器登陆了,这就为应用的扩展提供了便利。
流程上是这样的:
用户使用用户名密码来请求服务器
服务器进行验证用户的信息
服务器经过验证发送给用户一个token
客户端存储token,并在每次请求时附送上这个token值
服务端验证token值,并返回数据
这个token必需要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,通常咱们在服务端这么作就能够了Access-Control-Allow-Origin: *。
那么咱们如今回到JWT的主题上。
JWT长什么样?
JWT是由三段信息构成的,将这三段信息文本用.连接一块儿就构成了Jwt字符串。就像这样:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
JWT的构成
第一部分咱们称它为头部(header),第二部分咱们称其为载荷(payload, 相似于飞机上承载的物品),第三部分是签证(signature).
加密
import jwt #只能对pyhton字典类型进行加密 第一个参数为须要加密的数据 第二个参数为密钥 第三个参数为加密算法 encoded_jwt = jwt.encode({'name':'你好'},'secret_key',algorithm='HS256') print(encoded_jwt) #加密后是一个二进制的数据 #结果>b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiXHU0ZjYwXHU1OTdkIn0.V3flV6UF3Hz0bCqzRTEs_1G46OAOuEM-ku22F14RJL4'
解密
import jwt # 解密 第一个参数为须要解密的数据 第二个参数为密钥(密钥输入错误会报错) 第三个参数为所用的加密算法 de_code = jwt.decode(encoded_jwt,'secret_key',algorithms=['HS256']) print(de_code) #结果> {'name':'你好'}
接口实例
#定义验证接口 def auth_required(): def decorator(view_func): def _wrapped_view(self,request, *args, **kwargs): import jwt encoded_jwt = jwt.encode({'username':'adimn'},'secret_key',algorithm='HS256') try: de_code = jwt.decode(encoded_jwt,'secret_key',algorithms=['HS256']) except Exception as e: return HttpResponse('没权限') return view_func(self,request, *args, **kwargs) # mystr = 0 # if mystr: # return view_func(self,request, *args, **kwargs) # else: # return HttpResponse('没权限') return _wrapped_view return decorator class MyTest(View): @auth_required() def get(self,request): return HttpResponse('123')