JWT-JSON WEB TOKEN
一、JWT前传—— Cookie和Session
1.Cookie
cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。
cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网
站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,
同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
2. Session
session 从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?
对方肯定有某种特征(长相等)表明他就是张三。session 也是类似的道理,服务器要知道当前发请求给自己的是谁。
为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,
服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用
cookie 的方式。服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。
这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求
到了另一台服务器的时候session会丢失。
3. cookie和session的区别
session是存储服务器端,cookie是存储在客户端,所以session的安全性比cookie高获取session里的信息是通过存放在会话
cookie里的session id获取的。而session是存放在服务器的内存中里,所以session里的数据不断增加会造成服务器的负担,
所以会把很重要的信息存储在session中,而把一些次要东西存储在客户端的cookie里。session的信息是通过sessionid获取的,
而sessionid是存放在会话cookie中当浏览器关闭的时候会话cookie消失,所以sessionid也就消失了,但是session的信息还存
在服务器端,只是查不到所谓的session,但它并不是不存在
此处转载:
https://www.cnblogs.com/liuqingzheng/p/8990027.html
二、JWT前传—base64
加密也能解密 ‘防君子不防小人’
概念:
base64 可以把字符串编码成base64的编码格式:(大小写字母,数字和 =)
eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjosdknwkfnImxxeiIsICJhZG1pbiI6IHRydWV9
base64可以把base64编码的字符串,解码回原来的格式
应用场景:
1. jwt中使用
2. 网络中传输字符串就可以使用base64编码
3. 网络中传输图片,也可能使用base64的编码
主要有如下:
b64encode、b64decode、urlsafe_b64encode、urlsafe_b64decode
三、JWT前传——HMAC-SHA256
HMAC-SHA256是一种通过特别计算方式之后产生的消息认证码,使用散列算法同时结合一个加密秘钥。他可以用来保证数据的完整
性,同时可以用来作某个消息的身份验证。
import hmac
# 生成hmac'对象
# key为加密的key,bytes类型
# str为预加密的串,bytes类型
# 第三个参数为hmac的算法,指定为SHA256
key = ''
h = hmac.new(key, str, digestmod='SHA256')
h.digest()
四、JWT-json-web-token
Json web token是为了在网络应用环境间传递生命而执行的一种基于JOSN的开放标准,JWT的声明一般被用来在身份提供者
和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。
JWT结构
就是令牌token,是一个String字符串,由3部分组成,中间用点隔开
令牌组成: 标头(Header) 有效载荷(Payload) 签名(Signature) token格式:head.payload.singurater 如:xxxxx.yyyy.zzzz
JWT-header
有令牌的类型和所使用的签名算法,如HMAC、SHA256、RSA;使用Base64编码组成;(Base64是一种编码,不是一种加密过程,可以被翻译成原来的样子)
格式为字典-元数据格式如下
{'alg': 'HS256', 'typ': 'JWT'}
# alg代表要使用的算法
# typ表明该token的类别-此处必须为大写的JWT
# 该部分数据需要转成json串并用base64转码
JWT-payload
有效负载,包含声明;声明是有关实体(通常是用户)和其他数据的声明,不放用户敏感的信息,如密码。同样使用Base64编码 格式为字典-此部分分为共有声明和私有声明
公有声明: JWT提供了内置关键字用于描述常见的问题,此部分均为可选项,用户根据自己的需求,按需添加key,常见的公共声明如下:
{ 'exp':xxx, #Expiration Time,此Token的过期时间的时间戳
'iss':xxx, #(Issuer)Claim指明此token的签发者
'iat':xxx, # Issued at Claim 知名此创建时间内的时间戳
'aud':xxx, # Audience Claim 指明此Token签发面向群体
}
特殊说明: 若encode得时候payload中添加了exp字段;则exp字段的值需为 当前时间戳+此token的有效期时间,例如希望token 300秒后过期
{‘exp’:time.time()+300};在执行decode时,若检查到exp字段,且token过期,则抛出
jwt.ExpiredSignatureError.
私有声明: 用户可根据自己的业务需求,添加自定义的key,如下:
{'username': 'guoxiaoxiao'}
公有声明和私有声明均在同一个字典中,转成json串并用base64转码
JWT-signature
根据header中的alg确定具体算法,以下用HS256为例 HS256(自定义的key,base64后的header + ‘.’+base64后的payload)
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret);
签名目的: 签名的过程实际上是对头部以及负载内容进行签名,防止内容被窜改。如果有人对头部以及负载的内容解码之后进行修改,
再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。 如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。
信息安全问题: Base64是一种编码,是可逆的,适合传递一些非敏感信息;JWT中不应该在负载中加入敏感的数据。 如传输用户的ID被知道也是安全的,如密码不能放在JWT中;JWT常用于设计用户认证、授权系统、web的单点登录。
JWT-校验规则与流程
- 解析header,确认alg。
- 签名校验-根据传过来的header和payload按alg指明 的算法进行签名,将签名结果和传过来的sign进行对比,若对比一致,则校验通过。
- 获取payload自定义内容。
前后端分离场景下 使用JWT
原则:
- JWT签发后,交由浏览器保存。
- 浏览器可将其存储在"本地存储"中。
- 需要 用户登陆 才能使用的功能,前端ajax中需要将jwt传至后端,可放在请求头中发送。