JSON Web Token(JWT)是一种可以在多方之间安全共享数据的开放标准,JWT 数据经过编码和数字签名生成,可以确保其真实性,也因此 JWT 通常用于身份认证。这篇文章会介绍什么是 JWT,JWT 的应用场景以及组成结构,最后分析它的优点及局限性。
在介绍 JWT 之前,先看下传统认证方式有什么问题,这里的传统认证方式是指 Session-Cookie
方式。有小伙伴可能要说了,传统认证方式能有什么问题,如果有问题肯定是你代码写的不好。其实不是,有些问题存在于方案本身。
先来看一下传统的认证方式流程:
这是常见的认证流程,但是这种认证方式存在下面几个问题。
状态存储负担
Session-Cookie
方式因为服务端要存储当前会话信息,而且必不可少, 这就额外增加了存储负担,而且在分布式系统中,还要考虑不同机器之间的会话状态同步问题。有时还需要部署独立的认证服务。不易维护。
跨域问题
基于 Cookie 会话的认证方式,在进行跨域请求时存在难点,Cookie 不会跟随跨域请求。认证信息带不过去,当然,聪明的小伙伴可以通过设置客户端参数,配置服务端参数等操作来允许跨域,不过有点麻烦了。
CSRF 攻击风险
CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种常见的 Web 安全漏洞。有些小伙伴不知道是什么意思,看下面流程:
QQ 空间曾经也确实出现过 CSRF 漏洞。
在解决这几个问题上,JWT 具有天然优势,它存储在客户端,服务端无状态。Token 可以不存在 Cookie 中,轻松跨域又减少了 CSRF 风险。
JWT(JSON Web Tokens)它定义了一种紧凑且自包含的方式用于在各方之间作为 JSON 对象安全地传递信息。紧凑意味着内容尽可能的短小。自包含意味着内容中包含了身份信息。这个信息可以用于身份认证,也可以用于信息交换。由于信息会使用密钥进行数字签名,因此JWT 可以被验证以及信任。
常见的 JWT 应用常见有 JWT 授权和信息交换:
JWT 由小数点分割的三部分组成,如 xxxxx.yyyyy.zzzzz
,这三部分对应的是的标头(Header)、负载(Payload)、签名(Signature),每部分使用 Base64Url 进行编码,
下面是一个真实 JWT 示例:
JWT 示例
注意:JWT 为紧凑形式,没有换行,这里为了方便阅读,进行了换行。
Header 部分 Base64Url 解码后可以看到两个字段,alg
指定签名算法,typ
指定 Token 类型。
{
"alg": "HS256",
"typ": "JWT"
}
对上述标头对象进行 Base64Url 编码以形成 JWT 的第一部分。
第二部分中存放了实际需要的数据,用户可以自定义内容,如用户身份信息。
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
同时 JWT 也规定了几个官方字段:
iss (issuer):签发人
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
exp (expiration time):过期时间
iat (Issued At):签发时间
jti (JWT ID):编号
可以看到不管第一部分还是第二部分,字段名都是三位字母,这也是为了内容的紧凑。对 JWT 负载进行 Base64Url 编码以形成 JWT 的第二部分。
特别注意:由于只要 Base64Url 解码就可以看到第二部分内容,因此不能在 Payload 中存储敏感信息。
签名 Signature 的生成依赖标头 Header 和负载 Payload ,同时要有拥有用于签名的密钥,因此签名可以用于验证 JWT 的发送者是否正确,并确保消息没有被篡改。
Signature = HMACSHA256(
base64UrlEncode(header) + '.' +
base64UrlEncode(payload),
secret)
JWT 官网也提供 JWT 在线解码验证工具[1],可以访问查看。
JWT 在线验证
使用 JWT 进行身份认证的工作流程如下:
Authorization: Bearer <token>
JWT 有下面几个特点。
JWT 存在优点,也有很多风险与挑战,参考前人的最佳实践可以少走弯路。
总体而言,JWT 提供了一种相对简单且有效的方式来处理身份验证问题,但是需要注意JWT 安全性和细节问题,以确保 JWT 可以在应用中正确且安全地使用。
预告:下一篇文章会介绍如何在 Java 中使用 JWT 进行身份验证。
参考
[1]
JWT 在线解码验证工具: https://jwt.io/?_gl=1*1igv4lh*_ga*NTkxODM4NDM2LjE3MTA1ODM3NTM.*_ga_QKMSDV5369*MTcxMDgwOTgyOS40LjEuMTcxMDgxMDgyNC41Ny4wLjA.
---- END ----
"Hello world : ) 我是阿朗,这里记录一线大厂工具人的学习、生活与见闻"