在上一篇文章中,我们探讨了通过 Cookie-Session 机制来管理对话和保持用户登录状态的早期解决方案。尽管这一方法有效地解决了问题,但它依然存在一些不可忽视的局限性。特别是在高并发环境下,频繁的查询操作会导致性能显著下降;此外,在分布式集群或微服务架构中,这种传统的会话管理方式也显示出较差的扩展性。为了解决这些问题,一种新的身份验证方式—— Token 应运而生。
Token 是一种用于身份验证和授权的机制。它通常是一个字符串,包含了用户的身份信息和其他相关数据。当用户成功登录后,服务器会生成一个Token并将其返回给客户端。客户端在后续的请求中将这个Token包含在请求头中,服务器通过验证Token来确认用户的身份和权限。
在token发展的早期,最初有两种token:
一种是服务器生成的随机字符串,另一种是base64编码的token(包含用户信息),这两种token在早期都被用来做过用户校验,它们的工作原理是:都是由服务器自己生成,服务器自己存一份,再给用户发一份,用户将这份信息存储在localStorage中,每次登录都拿着token去校验,校验通过,服务器通过这个token将和用户相关联的数据发送过去。
但是呢,它并没有经过任何的加密,base64也只是编码而非加密,所以安全性极差。
这样乍一听好像和cookie-session的存储方式没什么区别啊?确实!早期的token和cookie-session的存储方式确实没有什么区别,它并没有解决cookie-session存储在高并发下或者在分布式下的问题。但是后来它的一个变种 JSON Web Token 也就是 JWT , 解决了这个问题。
JSON Web Token (JWT) 是一种开放标准 (RFC 7519),用于在网络应用环境间安全地将信息作为 JSON 对象传输。JWT 通常用于身份验证和信息交换。
它也是token的一种,不同的是它有着特殊的结构,非常利于身份认证,它是这样组成的:
JWT 由三部分组成,每部分之间用点号(.)分隔:
Header(头部) :包含令牌的类型(即 JWT)和所使用的签名算法(如 HMAC SHA254 或 RSA)。 Payload(载荷) :包含声明(claims),这些声明是关于实体(通常是用户)和其他数据的声明。 Signature(签名) :用于验证消息在此过程中没有被更改,并且对某些使用场景来说,对发送方的身份进行确认。下面是一个JWT的例子:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 .eyG1c2VyIjp7ImlkIjoxMTQ1MTQsInVzZXJuYW1lIjoiU2t5ZSIsInBhc3N3b3JkIjoiMTIzNDU2In0sImlhdCI6MTc1NjA5MjE5NiwiZXhwIjoxNzU2MTc4NTk2fQ .w0bBpjyhXCIkVqy8lMZgg1Dhhp2N2SCNj7QA4A55T6o
最上面的是 Header ,一般包括令牌类型和加密用的算法,
中间是 Payload , 在用户认证时,这里通常传入用户的id,username,但不会传入密码,
因为 Header和Payload都只是进行了base64编码,而没有加密,可以很简单的解码,得到其中的内容。
你可以在 www.jwt.io/ 这个网站验证你的JWT是否还有效,也可以直接解码,看到payload中的内容。
最后是Signature,它是由Header和Payload以及 Secret Key 经过某些算法加密得到的字符串,在身份验证中,最重要的就是这一个字符串。
Secret Key是一段字符串,可以由我们自定义,它存储在服务器端,用来校验JWT的正确性。
客户端请求认证:
客户端向服务器发送用户名和密码(或其他认证信息)进行登录。服务器验证信息并生成 JWT:
服务器验证用户名和密码,如果验证成功,服务器会生成一个 JWT 并将其返回给客户端。客户端存储 JWT:
客户端将 JWT 存储在本地(如 LocalStorage、SessionStorage 或 Cookie)。客户端发送带有 JWT 的请求:
客户端在后续请求中将 JWT 放在 HTTP 请求头中的 Authorization 字段中(通常是 Bearer <token> 格式)。服务器验证 JWT:
服务器从请求头中提取 JWT,解码并验证其签名。如果签名有效,服务器解析出其中的声明,并根据需要进行进一步处理。服务器通过还原Signature来验证JWT,这里是整个 JSON Web Token 的重点,也是它区别于cookie-session做了优化的点。
当我们传输一个JWT的时候,服务器接收到以后会进行解码,服务器会从Header中解析出token类型和应用算法,它会从Payload之中解析出我们传入的用户关键信息,最后,服务器自己会存有一个Secrect Key, 当把Header和Payload解码完毕之后,服务器将会把它们俩连着Secret Key一起按照Header解析出的算法进行加密,最终加密成一个字符串,和Signature比较,如果相同,则通过验证。
我们说了Cookie-Session存储模式有一些缺点,在进行高并发的时候,会频繁查询数据库导致性能低下,在进行分布式的架构中,多个服务器还得共享一个远程数据库进行查询操作,也造成性能低下,那么JWT是如何解决的呢?
Cookie-Session的性能问题是这样产生的:
ClientServerDatabase
请求(含session_id)SELECT * FROM sessions WHERE session_id = 'abc123'返回session数据可能还有业务查询(如商品信息)响应ClientServerDatabase
问题就在于,无论进行什么操作,都必须经过Session查询。 总要有Session查询用户id等信息再向数据库进行请求相关数据。这样麻烦,而且服务器中的SessionId每个用户还都不一样,当同一时间大量用户涌入,会创建好多个id,会同时进行上万次的查询操作,这个时候就要看服务器绷得住不了....
而 JWT 恰恰是优化了这一点,性能同样的电商场景,使用JWT时:
登录时生成JWT,仅将必要信息(如user_id)嵌入令牌,不存储完整数据:{ "sub": "1001", "prefs": ["dark_mode", "zh_CN"], "iat": 1620000000, "exp": 1620086400 } 关键区别:购物车等可变数据不存入JWT(因为JWT不可变),仍存数据库。
而它的请求逻辑处理是这样的:
ClientServerDatabase
alt[需要动态数据(如购物车)][仅需身份(如API鉴权)]请求(含JWT)验证签名/过期时间(无需查库)
SELECT * FROM carts WHERE user_id = 1001直接响应(无库操作)ClientServerDatabase
优化点:
静态请求(如获取用户昵称):直接从JWT解析user_id,无需查session表。 动态请求(如购物车):按需查询业务表,跳过session验证步骤。在 Session 的验证中,不管什么操作,都需要先击穿Session,由Session_id查找对应用户id等信息,再查找数据库的数据,而在 JWT 中,我们可以直接从 JWT 中解析出用户的必要信息,直接进行查询,这样我们的步骤就比Session要少一步,少这一步就能优化很多性能。
分布式或微服务架构带来的问题我们都知道 Cookie-Session的存储模式,一般是将临时的 session_id 以及一些信息存储在服务器中,而一般我们都会选择多个服务器来承载用户,当我的session数据存在了A服务器中,但我访问网站时A满了,把我匀给B服务器来处理我的请求了,但是此时B服务器并没有我的session信息,就会导致我的登录状态等出现问题。
所以一般我们都会选择存储在一个公共的远程数据库中,可能会用 Redis 集中存储。但是这样就造成了我们维护在线状态的成本加大。但是利用 JWT 就可以解决这个问题。
JWT 的设计理念核心就是 secret-key , 我们能解码出 Header 和 Payload 的内容,但是想还原 Signature , 还得靠一个 Secret-key 字段,JWT不用实现访问数据库进行校验,服务器自己就能进行逻辑校验,而校验所用的 Secret-key,就存储在本服务器上。我们如果利用分布式或者微服务架构,只需要在每一台服务器上设置同一个 Secret-Key 就可以了。
JWT也是一些别的特点的,它被签发后无法被修改内容,例如其中的数据(用户角色,权限),且其在有效期内是不会变的,如果管理员在JWT有效期内修改了用户的角色,比如从“普通用户”变为了“管理员”,那么用户的JWT仍然会携带旧的角色信息。要想让其新的角色信息生效,只能是等待JWT到期,或者强制用户重新登录获取新的JWT。
由于JWT的无状态性,服务器不知道哪些JWT正在被使用,如果某个JWT泄露,就有了安全隐患,服务器也无法使它在过期之前让它失效,我们无法像对待Session一样,直接将它从列表中删除,让它失效。
所以说,JWT适用于一些短有效期场景,适用于一些权限更改较少的场景。
而Session存储可以做到实时更新权限,可以随时删除Session,强制用户重新登录,权限变更后立刻生效,适用于高安全性场景,如金融支付等场景,我们可以随时冻结不正常的卡233333~
通过这一期文章我们终于知道了为什么JWT在某些方面要优于Cookie-Session的原因了。下一期我们将利用apifox和jwt来mock数据,看看这个jwt到底怎么用!
相关知识
还不会JWT?花5(15)min读完这篇文章就可以了!
生姜在幼苗期要如何掌握培育方法?读完这篇一目了然
滴水观音的市场价格是多少?看完这篇文章,您是不是被坑了
养花不会繁殖花,简直就是浪费钱,6种漂亮花,现在就可以扦插了
火龙果疏花疏果技术,你了解多少?这篇文章全讲明白了
看完这篇文章的百分之九十九的都脱单了—七夕表白攻略
SpringBoot 项目 + JWT 完成用户登录、注册、认证用户登录、注册及鉴权是我们基本所有系统必备的,也是很核心
石榴多种繁殖技术,这篇文章告诉你。
环保科普丨烟花爆竹的危害,读完这篇你就懂了
富贵竹要养对,才能常年绿油油的!读完文章回家试试
网址: 还不会JWT?花5(15)min读完这篇文章就可以了! https://m.huajiangbk.com/newsview2267240.html
上一篇: 椒花水库下闸蓄水安全鉴定咨询服务 |
下一篇: 区块链+数字指纹识别技术=工业物 |