最新: 免费获取 JWT 手册,深入了解 JWT!
JSON Web 令牌 (JWT) 是一种开放标准 (RFC 7519),它定义了一种紧凑且自包含的方式,用于以 JSON 对象的形式在各方之间安全地传输信息。此信息可以被验证和信任,因为它经过数字签名。JWT 可以使用密钥 (使用 HMAC 算法) 或使用 RSA 或 ECDSA 的公钥/私钥对进行签名。
虽然 JWT 可以被加密以在各方之间提供保密性,但我们将重点关注签名令牌。签名令牌可以验证其中包含的声明的完整性,而加密令牌则隐藏这些声明,使其无法被其他方访问。当令牌使用公钥/私钥对进行签名时,签名还证明只有持有私钥的一方才能对其进行签名。
以下是一些 JSON Web 令牌有用的场景
授权:这是使用 JWT 的最常见场景。用户登录后,每个后续请求都将包含 JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是如今广泛使用 JWT 的一项功能,因为它开销小,并且能够轻松地在不同域之间使用。
信息交换:JSON Web 令牌是各方之间安全传输信息的良好方式。由于 JWT 可以被签名(例如,使用公钥/私钥对),因此您可以确定发送方就是他们自称的那个人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。
在紧凑形式中,JSON Web 令牌由三个部分组成,它们用点 (.
) 分隔,分别是
因此,JWT 通常如下所示。
xxxxx.yyyyy.zzzzz
让我们分解不同的部分。
标头通常包含两个部分:令牌类型,即 JWT,以及正在使用的签名算法,例如 HMAC SHA256 或 RSA。
例如
{
"alg": "HS256",
"typ": "JWT"
}
然后,此 JSON 被Base64Url编码,以形成 JWT 的第一部分。
令牌的第二部分是有效负载,它包含声明。声明是关于实体(通常是用户)和附加数据的陈述。声明有三种类型:注册、公共和私有声明。
注册声明:这是一组预定义的声明,它们不是强制性的,但建议使用,以提供一组有用的、可互操作的声明。其中一些是:iss(发行者)、exp(过期时间)、sub(主体)、aud(受众)以及 其他。
请注意,声明名称只有三个字符长,因为 JWT 旨在保持紧凑。
公共声明:这些声明可以由使用 JWT 的人随意定义。但为了避免冲突,它们应该在 IANA JSON Web 令牌注册表 中定义,或者定义为包含防冲突命名空间的 URI。
私有声明:这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明,也不是公共声明。
一个示例有效负载可能是
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
然后对有效负载进行Base64Url编码,以形成 JSON Web 令牌的第二部分。
请注意,对于签名令牌,此信息虽然受到篡改保护,但任何人都可以读取。不要将机密信息放在 JWT 的有效负载或标头元素中,除非它被加密。
要创建签名部分,您必须获取编码的标头、编码的有效负载、密钥、标头中指定的算法,并对其进行签名。
例如,如果您想使用 HMAC SHA256 算法,则签名将以以下方式创建
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
签名用于验证消息在传输过程中没有被更改,并且,对于使用私钥签名的令牌,它还可以验证 JWT 的发送方就是他们自称的那个人。
输出是三个用点分隔的 Base64-URL 字符串,它们可以轻松地在 HTML 和 HTTP 环境中传递,同时与 SAML 等基于 XML 的标准相比更加紧凑。
以下显示了一个具有先前编码的标头和有效负载的 JWT,并且它使用密钥进行签名。
如果您想玩 JWT 并将这些概念付诸实践,您可以使用 jwt.io 调试器 来解码、验证和生成 JWT。
在身份验证中,当用户使用其凭据成功登录时,将返回一个 JSON Web 令牌。由于令牌是凭据,因此必须格外小心以防止安全问题。一般来说,您不应该将令牌保留超过必要的时间。
您还 不应该将敏感的会话数据存储在浏览器存储中,因为缺乏安全性。
每当用户想要访问受保护的路由或资源时,用户代理应该发送 JWT,通常在使用 Bearer 模式 的 Authorization 标头中。标头的内容应该如下所示
Authorization: Bearer <token>
在某些情况下,这可能是一种无状态授权机制。服务器的受保护路由将检查 Authorization
标头中是否存在有效的 JWT,如果存在,则允许用户访问受保护的资源。如果 JWT 包含必要的数据,则可能减少了查询数据库以执行某些操作的需要,尽管这并不总是如此。
请注意,如果您通过 HTTP 标头发送 JWT 令牌,则应尝试防止它们变得太大。一些服务器不接受标头中超过 8 KB 的数据。如果您尝试在 JWT 令牌中嵌入太多信息,例如通过包含所有用户的权限,您可能需要其他解决方案,例如 Auth0 细粒度授权。
如果令牌是在 Authorization
标头中发送的,则跨域资源共享 (CORS) 不会成为问题,因为它不使用 cookie。
下图显示了如何获取 JWT 并将其用于访问 API 或资源
/oauth/authorize
端点进行操作。请注意,对于签名令牌,令牌中包含的所有信息都暴露给用户或其他方,即使他们无法更改它。这意味着您不应该在令牌中放置机密信息。
让我们讨论一下与 简单 Web 令牌 (SWT) 和 安全断言标记语言令牌 (SAML) 相比,JSON Web 令牌 (JWT) 的优势。
由于 JSON 比 XML 冗长,因此在编码时,它的尺寸也更小,使 JWT 比 SAML 更紧凑。这使得 JWT 成为在 HTML 和 HTTP 环境中传递的良好选择。
在安全性方面,SWT 只能使用 HMAC 算法通过共享密钥进行对称签名。但是,JWT 和 SAML 令牌可以使用 X.509 证书形式的公钥/私钥对进行签名。与 JSON 签名的简单性相比,在不引入模糊的安全漏洞的情况下对 XML 使用 XML 数字签名非常困难。
大多数编程语言中都普遍存在 JSON 解析器,因为它们直接映射到对象。相反,XML 没有自然的文档到对象的映射。这使得使用 JWT 比使用 SAML 断言更容易。
在使用方面,JWT 在互联网范围内使用。这突出了在多个平台上,尤其是移动平台上,客户端对 JSON Web 令牌的易于处理性。
比较编码的 JWT 和编码的 SAML 的长度
如果您想了解更多关于 JSON Web 令牌的信息,甚至开始使用它们在您自己的应用程序中执行身份验证,请浏览 Okta 的 JSON Web 令牌登录页面。
立即开始使用 JWT
开始使用该工具