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

你真的了解JWT(JSONWebToken)吗?

时间:2023-03-14 19:41:44 科技观察

颁发访问令牌是授权服务的关键。OAuth2.0规定不限制accesstoken内容的生成规则,只要满足唯一性、不连续性、不可猜测性即可。结构化的令牌比随机字符串更易读,最常用的是JWT。什么是JWT?JWT是一个开放标准(RFC7519),它定义了一种紧凑且自包含的方式来安全地将信息作为JSON对象传输并在结构化包中生成令牌。结构化的token可以被赋予丰富的含义,这是与无意义的随机字符串形式的token最大的区别。JWT的结构是怎样的?HEADER(头部)加载token类型、算法等信息,是JWT的头部。typ表示PAYLOAD的第二部分是JWT类型alg表示使用HS256对称签名的算法PAYLOAD(数据体)是JWT的数据体,代表一组数据。subtoken的主题一般设置为资源拥有者的唯一标识。exptoken的过期时间戳iattoken颁发的时间戳是JWT规范的声明。PAYLOAD表示的数据集允许我们自定义语句。SIGNATURE(签名)签名后的JWT整体结构分为三部分:header.payload.signature。JWTtoken肉眼看起来没什么意义,但是如果你把它复制到https://jwt.io/进行在线验证,就可以看到解码后的有意义的数据。SIGNATURE表示JWT信息的签名。Function你可能认为有了HEADER和PAYLOAD,token携带的信息就可以在网络中传输,但是在网络中传输这样的信息是不安全的。签名必须加密,SIGNATURE是信息签名的结果。当受保护资源收到第三方软件的签名时,需要验证token的签名是否合法。令牌内部检查定义,由于授权服务颁发令牌,因此受保护资源服务必须验证令牌。受保护资源调用授权服务提供的验证令牌服务的令牌验证方式称为令牌内部检查。特性有时授权服务依赖于一个DB,那么受保护的资源服务也依赖于这个DB,即“共享DB”。在微服务架构下,不同的系统依赖服务而不是DB通信。比如授权服务为受保护的资源服务提供RPC服务:JWTtoken本身包含了之前依赖DB或者RPC服务获取的信息,比如某某软件的用户授权等信息.如何使用JWT令牌?JWTtoken后的通信方式授权服务发送token,受保护资源服务收到token,然后开始解析token中包含的信息,不需要查询DB或RPC调用。即实现了token内部检查。为什么要对代币进行编码和签名?授权服务下发JWT后,交给xx软件,xx拿着token请求受保护的资源服务,就是我在公众号的文章。显然token是要在公网上传输的。因此,在传输过程中,令牌还必须:编码,防止乱码;签名加密,防止数据信息泄露。JJWT是一个更方便的开源JWT工具,开箱即用。封装Base64URL编码、对称HMAC、非对称RSA的一系列签名算法。使用JJWT可以轻松生成签名的JWTtoken并解析JWTtoken。StringsharedTokenSecret="helloauthhelloauthhelloauthhelloauth";//KeyKeykey=newSecretKeySpec(sharedTokenSecret.getBytes(),SignatureAlgorithm.HS256.getJcaName());//生成JWTtokenStringjwts=Jwts.builder().setHeaderParams(headerMap).setClaims(payloadMap).signWith(key,SignatureAlgorithm.HS256).compact()//解析JWT令牌);Claimsbody=claimsJws.getBody();JWT代币的优势?计算代替存储时间进行空间思考。这种计算和结构封装减少了远程调用“共享DB”带来的网络传输性能损失,因此可能节省时间。加密因为JWTtoken中已经包含了重要信息,所以传输过程必须要求密文传输,强制加密也保证了传输安全。增强系统的可用性和可扩展性JWTtoken通过“自编码”的方式包含认证所需的信息,不需要在服务器端额外存储,因此每个请求都是一个无状态会话。尽可能遵循无状态架构设计原则,增强系统的可用性和可扩展性。JWTtoken的缺陷是在使用过程中无法修改token状态。比如我在使用xx的时候,可能会在公众号平台上无故修改密码或者突然取消对xx的授权。这时候应该改变token的状态,原来对应的token会失效。但是使用JWT时,每次下发的token在服务器上是不存在的,token的状态是无法改变的。这表明JWT令牌在其有效期内已解锁。那么是否可以将JWTtoken存储在Redis等分布式内存数据库中呢?不!这违背了JWT的要点——将结构化的信息存储到令牌本身中。通常有两种解决方案:将每次生成JWTtoken的秘钥粒度减小到用户级别,即每个用户一个秘钥。这样,当用户取消授权或更改密码时,可以一起修改密钥。此解决方案通常需要由单独的密钥管理服务支持。在不为用户提供主动解除授权的环境下,如果只考虑修改密码的场景,可以使用用户密码作为JWT密钥。这也是用户粒度。这样,用户修改密码就相当于修改了密钥。Token生命周期Token是有有效期的,但是JWT可以在自己的结构体中存储有效期信息。OAuth2.0的token生命周期通常有三种情况:1.token自然过期。这个过程不排除主动销毁token的可能。例如,如果令牌泄露,授权服务可以使令牌无效。2、accesstoken过期后,可以通过refreshtoken请求新的token,提高用户使用第三方软件的体验。3、让xx等第三方软件主动发起token失效请求,然后授权服务收到请求后会立即将token失效。什么时候需要这个机制?比如用户和第三方软件有一个排序关系:我购买了xx软件,到期或者退订时,我授权的token还没有过期,需要这样的token提现协议支持xx主动发起令牌失效请求。作为一个开放平台,也建议负责任的第三方软件遵守这样的代币提现协议。总结OAuth2.0的核心是授权服务,没有token就没有OAuth,token代表授权结果。令牌对于OAuth2.0系统中的第三方软件是不透明的。需要关心令牌的是授权服务和受保护的资源服务。JWT默认不加密,但也可以加密。生成原始Token后,可以使用密钥再次加密JWT。如果不加密,则无法将机密数据写入JWT。JWT不仅可以用于身份验证,还可以用于交换信息。有效使用JWT可以减少服务器查询数据库的次数。JWT最大的缺点是由于服务器端不保存会话状态,所以在使用过程中无法撤销令牌或更改令牌的权限。也就是说,JWT一旦下发,就一直有效,直到过期,除非服务端部署了额外的逻辑。JWT本身包含身份验证信息。一旦泄露,任何人都可以获得通证的所有权限。为了减少盗用,JWT的有效期应该设置的比较短。对于一些比较重要的权限,用户在使用时需要重新认证。为了减少盗用,JWT不应使用明文的HTTP协议传输,而应使用HTTPS协议传输。请参阅JSONWeb令牌入门教程。在OAuth2.0中,如何使用JWTstructuredtokenCard?https://tools.ietf.org/html/rfc6749#section-4.4