Cookie和Session与JWT的区别
Cookie
和Session
这两种传统模型,有一个缺点,它们都不支持横向拓展,也就是不支持分布式架构(不支持服务器集群)。
我们先不说用户的访问量有多大,为了高可用,一般来说都会布置一台以上的服务器。如果是一个服务器集群的话,一台服务器访问量过多的时候,我们进行负载均衡,客户端的请求就会拐弯发送向别的服务器,这样我们是不是就不能保证每一次客户端都发送到同一台服务器上了。
当发送到不同服务器上时,那同一个客户端对应的Cookie
和Session
可能就不一样了(因为传统Cookie
和Session
都是端对端生成的,并不共享,所以它们不支持横向拓展)。那这样的话,客户端就没法验证身份了(或者是说另一台服务器并不能根据客户端发送过来的sessionID
在自己这台服务器里面查找到对应的身份认证信息)。客户端没法认证信息,就会登录失败,这就造成了问题。
当然现在已经有了一些分布式Cookie
和Session
的解决方案,这样不是不能解决分布式多机共享的问题,但是治标不治本,又会新增依赖性强的问题。
即中心化问题,Cookie
、Session
、Token
的会话数据都放在架设的中心化存储服务中(例如Redis
)。假使Redis
宕机了,那么所有的会话数据都会变得不可用。另外大量查询查中心化服务器也会导致性能瓶颈。
所以又诞生了JWT
,JWT
的认证数据是一种无状态的Token
。无状态可以理解为服务端并不会保存任何的会话数据,也就是说不会保存sessionID
这种数据,数据直接存在JWT
当中。
当客户端登录成功时,服务端就会创建一个无状态的Token
发给客户端浏览器,而当客户端浏览器收到这个Token
后,又会发送其他的请求给服务端。注意,客户端在发送其他请求给服务端时,是要携带上服务端发送过来的token
,不然会经过JWT
解析并验证直接请求失败。当解析和校验通过后,服务端便会把请求的信息发送回给客户端。
JWT
全称叫:JSON Web Token
,将整个信息加密在Token
中,服务端不会保存一点信息,因此这个Token
被称为无状态信息。
JWT
发送的Token
里有这些信息:①Header头部。②Payload荷载。③Signature签名。
整个JWT
的格式是JSON
格式。
①Header头部
alg: "HS256" //签名的算法是什么,JWT默认为HS256 typ: "JWT" //令牌类型,JWT默认就是JWT
②Payload荷载
iss: "发行人" //一般填企业的名称 exp: "到期时间" //保证token什么时候过期 sub: "主题" //随意,存一些想要交互的东西 aud: "用户" //存具体的用户ID标明用户是谁 nbf: "在某个时间前不可用" //可以用来设置预发布的时间 iat: "发布时间" //字面意思,啥时候发布 jtj: "JWT_ID用于表示JWT" //标识JWT //实际上这里面还能加,就看你想存什么
③Signature签名
//这部分是为了保证安全的 //签名部分主要是对前两个部分的数据签名,通过指定的算法(即Header头部的算法)生成哈希来确保数据不会篡改。
JWT
也有缺陷,它的第一个缺陷就是服务器并不会保存会话状态。例如一个用户的Token
还没有到期,但是我们想把它直接变成过期用户,那么这种情况是不能发生的,无法解决想要更改或者删除令牌这一操作。因为JWT
生成的Token
是无状态的,你并不能去篡改对应的数据让它立刻过期。
要想实现更改或者删除令牌这一操作,只能在服务端重新按原样交演一遍,存下对应的状态信息,但这样又违背了JWT
的理念。
JWT
第二个缺陷就是它并不是加密的,他虽然不能够去篡改,但它能被别人把前两个部分的信息解析出来。也就是说,JWT
内传递的信息保密性并不高,敏感信息很容易就泄露出去,因此不能够使用JWT
去传保密级别高的信息。
JWT
的第三个缺陷就是空间占用大,我们使用它的时候会把它结构的三个部分转成一个Base64
的格式,再给前端。token
内容这么大,通过网络IO传播的方式肯定要比Cookie和Session
的sessionID
这种方式空间占用大得多。
所以实际上我们并不能把JWT
当成Cookie和Session
使用,JWT
更适合一次性的令牌认证或者是极短时间的认证。
评论(0)