当前位置: 首页 > 科技观察

我师父把“JWT令牌”玩到了极致

时间:2023-03-15 20:26:00 科技观察

大家好,我是悟空。我的师父是唐玄奘~暑假你一定看过很多遍西游记的故事。为了得到真经,唐玄奘历经千辛万苦,终于得偿所愿。途经各国时,唐玄奘都会拿出一份通关证件,交给当地的国王盖章后才能通过。本文目录如下:通关证通关证是唐朝官方颁发的证明持有人为东唐人的证件,通常由使臣持有。有了这个证件以后,看到这个证件就可以去别的国家了,比如女儿国的国王。下面是西游记中通关文件的生命周期图。长安是一个发证(通关证件)的微服务节点。无极国度、女儿国度、大雷音寺都是集群中的微服务节点。唐玄奘带着证件游历各国。那么为什么其他国家承认这个证书呢?那是因为当时的唐朝非常强大,很多国家都想向唐朝进贡。结交大唐好处多多~贡品也是有故事的~唐太宗把微服务的“心跳机制”发挥到了极致!唐太宗在通关证上写道:“往西域诸国,不毁善缘,照证放行”。意思就是唐玄奘法师是我们唐朝的使者,希望大家放下。贞观年间,唐朝经济文化极为繁荣,国力强大。周边国家都希望与唐朝建立友好关系。给大唐留下了很好的印象。在安全架构中,凭据出现得太频繁了。比如我们在网关层添加的验证令牌,其实就是一个验证证书。什么是CredentialsCredentials的出现是系统保证其与用户之间的承诺是当时双方真实意图的反映,是准确、完整、不可否认的。唐太宗赐给唐玄奘的通关证是一种凭证,上面盖有唐朝官印和唐太宗亲笔亲笔,充分说明持证人具有可信的信物,而证上的凭证通关证明公章不可篡改。如果改了,其他国家就不承认了。上述模式其实对应的是一种常见的认证授权模式。大名鼎鼎的OAuth2.0认证授权模式虽然有五种模式,但都是同一个目标。最终的目的是为客户端生成一个证书,让客户端持有这个证书来访问资源。关于OAuth2.0本文不展开。关于凭证存储方案,目前业界安全架构有两种方案:Cookie-Session模式JWT方案Cookie-Session模式流程图如下:用户登录认证通过后,后台会存储用户的身份信息客户端,也就是存储在session中,可以通过session来区分,然后返回一个sessionId给客户端。客户端在客户端缓存sessionId。客户端下次发送HTTP请求时,会将header中的cookie字段连同sessionId一起发送给后端服务器。后端服务器获取header中的sessionId,然后根据sessionId找到session。如果session存在,则从session中解析出用户的身份信息,然后执行业务逻辑。我们都知道HTTP协议是一种无状态的传输协议。无状态意味着事务的处理没有上下文记忆,每个HTTP请求都是完全独立的。但是Cookie-Session模式与HTTP的无状态特性相违背,因为客户端在访问资源的时候,携带了第一次获取到的sessionId,这样服务端就可以成功的分辨出是谁发送了请求。服务器对session的管理是一种状态管理机制,存储了每个在线用户的context状态,加上一些超时自动清理的管理措施。Cookie-Session也是最传统的,但在今天仍然大量应用在系统中,是一种由服务端和客户端联动完成的状态管理机制。在西游记中,使用这种Cookie-Session模式会是什么感觉呢?我们把唐朝和周边国家看作一个分布式集群。各国都需要保存一份唐玄奘的使节信息(分布式存储)。当唐玄奘路过一个国家时,他需要检查一下有没有唐玄奘,如果有,就认为唐玄奘是合法的使者,可以放行。但是这种方式会需要每个国家同步保存,同步的成本非常高,而且会有同步延迟。Cookie-Session模式的优点是状态信息保存在服务器上。只要利用客户端的同源策略和HTTPS传输层的安全性,保证Cookie中的key值不被窃取,身份被冒用,就完全可以避免。上下文信息在传输过程中被泄露和篡改的风险。Cookie-Session方案的另一个优点是服务端具有主动状态管理能力,可以根据自己的意愿随时修改和清除任何上下文信息。例如,很容易实现强制用户下线的功能。(来自Phoenix架构)Cookie-Session模型的缺点对于单节点的单体服务来说是完美的,但是如果需要横向扩展部署集群就很麻烦了。如果session分配到不同的节点,部分用户的状态不重复保存,用户的请求固定分配到对应的节点。如果一个节点崩溃了,里面的用户态就会完全丢失。如果将session复制到所有节点,同步的代价会非常高。为了解决分布式条件下的认证授权问题,顺便解决state量小的问题,有JWTtoken方案,但是JWTtoken和Cookie-Session不是完全对等的解决方案,JWT只能处理认证授权问题,并不能说JWT比Cookie-Session更高级,也不可能完全替代Cookie-Sesion机制。JWT方案我们上面提到,Cookie-Session机制在分布式环境下会遇到一致性和同步开销的问题,而如果是在多方系统中,就更不可能在服务器端共享Session了多方系统,即使服务数据可以在终端之间共享,cookie也不能跨域。换个思路,服务端不保存任何状态信息,由客户端保存,每次发送请求时携带这个状态信息给后端服务。示意图如下:但是,这种方式不能承载大量信息,存在泄露和篡改的安全隐患。对于信息量有限没有更好的解决方案,但是要保证信息不被中间人篡改,可以使用JWT方案。JWT(JSONWEBTOKEN)是一种令牌格式,在分布式、多方系统应用系统中经常与OAuth2.0结合使用。我们先看看JWT格式长什么样:上面截图来自JWT官网(https://jwt.io),数据是悟空随机整理的。左边的字符串是JWT令牌。JWT令牌由服务器生成。每次发送请求时,客户端都会持有这个JWT令牌并将其放在HTTP标头中。右边是经过Base64解码后的JWT明文内容,在这个明文内容的底部,有一个签名内容,可以防止内容被篡改,但不能解决泄露问题。JWT格式JWTtoken以JSON结构存储,用点号分为三部分。第一部分是令牌头(Header),内容如下:{"alg":"HS256","typ":"JWT"}描述了令牌的类型(统一为typ:JWT)和令牌签名例子中的HS256是HMACSHA256算法的缩写。其他系统支持的签名算法可以参考https://jwt.io/网站。令牌的第二部分是载荷(Payload),也就是令牌真正需要传递给服务器的信息。但是服务端不会直接使用这个payload,而是通过对传输的Header和Payload进行加密,然后比对签名,判断payload是否被篡改,判断payload是否被篡改。如果没有,可以使用Payload中的内容。因为payload只是base64编码,没有加密,所以不安全。不要在负载中放置敏感信息,例如密码。{"sub":"passjava","name":"Wukongchatarchitecture","iat":1516239022}token的第三部分是签名(Signature),使用对象头中公开的具体签名算法,通过具体的密钥(Secret,由服务器保密,不能公开)对前两部分进行加密计算。以示例中使用的JWT默认的HMACSHA256算法为例,将通过以下公式生成签名值:HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)签名的含义:确保payload中的信息可信,没有被篡改,在传输过程中没有丢失任何信息。因为即使签名内容中的单个字节发生变化,也会导致整个签名发生重大变化。另外,由于签名只能由认证授权服务器完成(只有它知道Secret),篡改后任何人都无法重新计算合法的签名值,所以服务器可以完全信任客户端上传的JWT。加载信息。JWT的优点是无状态的:服务端不需要保存JWTtoken,也就是说服务节点不需要保存任何状态信息,认证功能可以在后续的请求中完成。天然扩展方便:服务水平扩展不需要考虑JWTtoken,但Cookie-Session需要考虑扩展后服务节点如何存储Session。不依赖cookies:JWT可以存储在浏览器的LocalStorage中,不一定存储在cookies中。JWTToken的缺点是难以主动作废:JWTtoken签发后,理论上与认证服务器无关,一直有效直至过期。除非服务端增加一些特殊的逻辑处理来缓存JWT,管理JWT的生命周期,否则这种方式会退化为有状态的服务。而这种有状态的需求是很常见的:比如用户注销后,用户需要重新输入用户名和密码才能登录;或者用户只允许在一台设备上登录,但在另一台设备上登录需要强制注销。但是这种有状态的模型降低了JWT本身的价值。更容易受到重放攻击:Cookie-Session也存在重放攻击的问题,即客户端可以用这个cookie连续发送大量请求,影响系统性能。但是因为session在server端也有一个副本,server端可以控制session的生命周期,更主动的应对重放攻击。但是JWT重放攻击对于服务端来说是非常被动的。比如通过客户端的验证码申请会比较麻烦,对服务器进行限流,或者缩短token的有效期。存在泄露风险:客户端存储很可能泄露出去,被其他人重用。有限的信息大小:HTTP协议不强制标头的最大长度,但服务器和浏览器有。并且如果token很大,会消耗传输带宽。真假孙悟空大话西游还有一章。假孙悟空带着通关证件和其他行李跑到花果山,想要自学经文。这不是盗用了JWTtoken吗?如何使用JWTJava有现成的工具可以使用,验证JWT的工作可以统一交给网关。这就是下一篇要讲解的实用内容。总结一下,唐玄奘就像一个客户端,通关文件就像一个JWTtoken,他经过的每一个国家就像一个集群中的微服务。唐玄奘利用JWT代币的认证授权模式,一路过关斩将,最终拿到了经书。是不是很爽~