JWT是什么
以下是官网的介绍
JSON 网络令牌(JWT)是一项开放标准(RFC 7519),它定义了一种紧凑、自足的方式,可在各方之间以 JSON 对象的形式安全地传输信息。由于该信息经过数字签名,因此可以验证和信任。JWT 可以使用密文(HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对进行签名。
它的本质能就是编码和加解了的字符串,但是在这个字符串携带了满足不同场景的JSON对象。
JWT可以用来做什么
授权:这是使用 JWT 最常见的情况。用户登录后,每个后续请求都将包含 JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是目前广泛使用 JWT 的一项功能,因为它的开销小,而且能在不同域间轻松使用。
信息交换:JSON Web 标记是在各方之间安全传输信息的好方法。由于 JWT 可以签名(例如,使用公钥/私钥对),因此可以确保发送者的真实身份。此外,由于签名是使用标头和有效载荷计算的,因此还可以验证内容是否被篡改。
看jwt的定义就知道就要用于验证和信任,所以jwt 的主要功能就是系统中的认证、和授权了。
小扩展
JWT和传统的token有什么不一样呢?
个人看来主要不一样的地方就是jwt通过自包含的方式来传输信息。当我们使用传统的token在使用的场景中客户端在请求接口时,在请求请求头中携带token 到服务器,然后服务器接收到了请求后获取的带了token 需要与服务器中存起来的token进行校验。比如在登录场景中不同的服务器中需要存入对应的登录状态,不能做到无状态的登录。如果使用jwt了客户端每次请求是携带jwt到服务端。服务端获取jwt进行校验操作。
JWT的结构
JSON Web Tokens 的简洁形式由三个部分组成,中间用点(.)隔开,它们是
- Header 标题
- PayLoad 有效载荷
- Signature 签名
因此,JWT 通常如下所示:
xxxxx.yyyyy.zzzzz
接下来分析一下这三个部分
(Header)标头
标头通常由两部分组成:令牌类型(JWT)和使用的签名算法(如 HMAC SHA256 或 RSA)。
{
"alg": "HS256",
"typ": "JWT"
}
然后,对 JSON 进行 Base64Url 编码,形成 JWT 的第一部分。
(Payload)有效载荷 令牌的第二部分是有效载荷,其中包含声明。声明要求是关于实体(通常是用户)和附加数据的声明。有三种类型的声明:注册声明、公共声明和私人声明。
- Registered claims(登记声明):这些是一组预定义的权利要求,不是强制性的,而是建议性的,目的是提供一组有用的、可互操作的权利要求。其中包括:iss(
issuer发布者)、exp(expiration time过期时间)、sub(subject主题)、aud(audience观众)等。
请注意,由于 JWT 本意是简洁,因此索赔audience名称只有三个字符。
-
Public claims(公开声明):使用 JWT 的用户可以随意定义。但为避免碰撞,应在IANA JSON Web Token Registry中进行定义,或定义为包含抗碰撞命名空间的 URI。
-
Private claims(私有声明):这些是为在同意使用的各方之间共享信息而创建的自定义权利要求,既不是注册权利要求,也不是公开权利要求。
有效载荷示例可以是
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
然后对有效负载进行 Base64Url 编码,形成 JSON 网络令牌的第二部分。
需要注意的是,对于已签名的令牌来说,这些信息虽然可以防止篡改,但任何人都可以读取。除非经过加密,否则不要在 JWT 的有效载荷或标头元素中加入秘密信息。
(Signature) 签名
要创建签名部分,必须使用编码后的报文头、编码后的有效载荷、密文、报文头中指定的算法,然后对其进行签名。
例如,如果要使用 HMAC SHA256 算法,签名将按以下方式创建:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
签名用于验证信息在传输过程中是否被更改,如果是用私钥签名的令牌,签名还可以验证 JWT 的发送者是否如其所言。
JWT是怎么工作的
在身份验证中,当用户使用凭据成功登录时,将返回一个 JSON 网络令牌。由于令牌是凭证,因此必须非常小心以防止出现安全问题。一般来说,保存令牌的时间不应超过所需的时间。
每当用户要访问受保护的路由或资源时,用户代理都应发送 JWT,通常是在使用承载器模式的授权(Authorization)标头中发送。头的内容应如下所示:
Authorization: Bearer <token>
在某些情况下,这可以是一种无状态授权机制。服务器的受保护路由会检查授权头中是否存在有效的 JWT,如果存在,用户就可以访问受保护的资源。如果 JWT 包含必要的数据,就可以减少某些操作对数据库的查询需求,但通常情况并非总是如此。
需要注意的是,如果通过 HTTP 标头发送 JWT 标记,应尽量避免其过大。有些服务器不接受超过8KB的标头。如果你想在 JWT 标记中嵌入过多信息,比如包含用户的所有权限,那么你可能需要一个替代解决方案,比如 Auth0 精细授权(Fine-Grained Authorization)。
下图显示了如何获取 JWT 并用于访问 API 或资源:
TODO 流程图
到此为止JWT的就介绍完了!