Shiro(八):JWT介绍
1、什么是JWT?
JWT(JSON Web Token,JSON Web令牌)是一种开放标准(RFC 7519),用于在网络应
用环境间安全地传递声明(claims)作为JSON对象;JWT会按指定的加密算法将该JSON对
象加密成一个字符串。
例如,服务器可以生成具有声明 “以管理员身份登录”(一般在 claims 中声明) 的令牌,并将
其提供给客户端,客户端可以使用该令牌来证明客户是以管理员身份登录的。令牌由服务器的
密钥签名,因此服务器能够验证令牌是否合法。
通俗的来讲,JWT就是一个用于加密或解密且不允许修改的字符串的字符串。
2、JWT的结构
JWT是一种紧凑的、URL安全的表示方式,用于在两方之间传输信息。它由三部分组成:
JWT格式:Header.Payload.Signature
1)Header(标头)
Header 主要包含JWT令牌类型和用于生成签名的加密算法,Header示例如下所示:
{"alg":"HS256","type":"JWT"
}
HS256 表示当前令牌使用 HMAC-HSA256 算法进行签名
2)Payload(有效负载)
Payload 主要包含声明(claims),即要传输的数据;是关于实体(通常是用户)和
其他数据的描述。有三种类型的声明:
I)注册声明:预定义声明,如iss, exp, sub, aud等
II)公开声明
III)私有声明
示例如下所示:
{"sub": "1234567890","name": "John Doe","admin": true,"iat": 1516239022
}
3)Signature(签名)
Signature 是将通过将编码后的header、编码后的payload、一个密钥和header中指定的
算法生成签名;用于验证消息在传输过程中没有被篡改。
签名的计算方式是:先使用base64url 对 标头Header 和 有效负载Payload 进行编码,
并将编码结果以英文句号(.)拼接起来,最后通过标头Header中的
加密算法对密钥key和拼接结果进行加密生成签名Signature,
如下所示:
//密钥
key = "secretKey"
//通过base64url对标头Header 和 有效负载Payload 进行编码,并以“.” 进行连接
unsignedToken = EncodeBase64(Header) + "." + EncodeBase64(Payload)
//生成签名key
signature = HMAC-HSA256(key,unsignedToken)
最后将Header 、Payload 和Signature 以英文句号(.)拼接在一起就是JWT。
为了将他们拼接在一起,我们将签名Signature也以base64url 进行编码,如下所示:
//生成JWTtoken = EncodeBase64(Header) + "." + EncodeBase64(Payload) + "." + EncodeBase64(signature)
3、JWT工作流程
JWT工作流程如下图所示:
3.1、客户端登录与JWT令牌获取
用户通过“用户名/密码” 的方法向认证服务器发送登录认证请求;服务器验证用户身份,若
验证通过,则生成JWT,并将生成的JWT返回给客户端
3.2、客户端携带JWT令牌访问资源
客户端将 JWT 存储在本地(如 localStorage
、sessionStorage
或内存)
客户端在后续请求通过 HTTP 头部(如 Authorization: Bearer <JWT>
)携带 JWT令牌
3.3、服务器验证JWT并处理后续请求
服务端从请求头中提取JWT令牌,并使用预共享的密钥或公钥验证签名是否有效,确保
JWT令牌未被篡改;JWT令牌校验通过则处理请求并返回处理结果,否则直接返回错误信息
3.4、令牌刷新
在实际工作中,一般给JWT设置较短的过期时间,当客户端jwt令牌过期后,执行
Refresh Token 向服务端请求新的JWT,即:短期JWT令牌 + 长期刷新JWT
4、JWT优点
相对于传统的Session,JWT有如下优点:
1)无状态,服务端不需要存储Session会话信息,降低服务端压力
2)支持跨域,适用于分布式系统和单点登录
3)灵活性好,JWT中可以包含用户自定义的数据(有效负载)
4)安全性好,JWT使用签名加密的方式,不允许被修改。
5、JWT使用场景
1)身份验证和授权
2)信息交换,可以包含自定义数据
3)分布式系统和单点登录
6、JWT使用时需要注意的点
1)不要将敏感信息放入JWT
2)最好使用HTTPS请求来传输JWT,更安全
3)JWT使用时需要设置合理的过期时间
4)使用强密钥