JSON Web Token (JWT)

224 阅读6分钟

什么是 JWT

JSON Web Token (JWT) 是一种开放标准 ( RFC 7519 ),它定义了一种紧凑且独立的方式,用于在各方之间以 JSON 对象的形式安全地传输信息。该信息可以被验证和信任,因为它是经过数字签名的。JWT 可以使用密钥(使用HMAC算法)或使用RSAECDSA的公钥/私钥对进行签名。

使用场景

授权

这是使用 JWT 最常见的场景。用户登录后,每个后续请求都将包含 JWT,从而允许用户访问该令牌允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能,因为它的开销很小并且能够轻松地跨不同域使用。

信息交换

JSON Web Token (JWT) 是在各方之间安全传输信息的好方法。因为 JWT 可以进行签名(例如,使用公钥/私钥对),所以您可以确定发送者就是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。

JSON Web Token 结构是什么 ?

在其紧凑形式中,JSON Web Token"."分隔的三个部分组成,它们是:

  • 头部
  • 有效负荷
  • 签名

因此,JWT 通常如下所示:

xxxxx.yyyyy.zzzzz

让我们分解不同的部分。

头部

头部通常由两部分组成:

  • 令牌的类型(JWT);
  • 所使用的签名算法(例如 HMAC SHA256 或 RSA)。

例如:

{
	"alg": "HS256",
	"typ": "JWT"
}

然后,对该 JSON 进行Base64Url编码以形成 JWT 的第一部分。

有效载荷

令牌的第二部分是有效负载,其中包含声明。

声明是关于实体(通常是用户)和附加数据的声明。

声明分为三种类型:

  • 注册声明:这些是一组预定义的声明,不是强制性的,而是推荐的,以提供一组有用的、可互操作的声明。 其中一些是: iss(发行者)、 exp(到期时间)、 sub(主题)、 aud(受众)
  • 公开声明:这些可以由使用 JWT 的人随意定义。但为了避免冲突,它们应该在 IANA JSON Web 令牌注册表中定义,或者定义为包含防冲突命名空间的 URI。
  • 私人声明:这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公共声明

有效负载示例可以是:

{
	"sub": "1234567890",
	"name": "John Doe",
	"admin": true
}

然后对有效负载进行 Base64Url 编码以形成 JSON Web Token 的第二部分。

签名

要创建签名部分,您必须获取编码的头部、编码的有效负载、密钥、头部中指定的算法,然后对其进行签名。

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

签名用于验证消息在传输过程中没有发生更改,并且在使用私钥签名的令牌的情况下,它还可以验证 JWT 的发送者是否是其所说的人。

将所有内容放在一起

输出是三个由"."分隔的 Base64-URL 字符串,可以在 HTMLHTTP 环境中轻松传递,同时与基于 XML 的标准(例如 SAML)相比更加紧凑。

下面显示了一个 JWT,它具有先前的标头和有效负载编码,并且使用密钥进行签名。

![[Pasted image 20230728232122.png]]

如果您想使用 JWT 并将这些概念付诸实践,您可以使用jwt.io 调试器来解码、验证和生成 JWT。

![[Pasted image 20230728232337.png]]

JSON Web 令牌如何工作

在身份验证中,当用户使用其凭据成功登录时,将返回 JSON Web Token。由于令牌是凭证,因此必须非常小心地防止安全问题。一般来说,您保留令牌的时间不应超过所需时间。

由于缺乏安全性,您也不应该将敏感会话数据存储在浏览器存储中。

每当用户想要访问受保护的路由或资源时,用户应该发送 JWT,通常在使用承载模式的头部 Authorization 选项中发送,头部的内容应如下所示:

Authorization: Bearer <token>

在某些情况下,这可以是无状态授权机制。服务器的受保护路由将检查标头中是否存在有效的 JWT Authorization,如果存在,则将允许用户访问受保护的资源。如果 JWT 包含必要的数据,则可能会减少查询数据库以执行某些操作的需要,尽管情况可能并非总是如此。

请注意,如果您通过 HTTP 标头发送 JWT 令牌,则应尽量防止它们变得太大。某些服务器不接受超过 8 KB 的头部。如果您尝试在 JWT 令牌中嵌入太多信息(例如包含所有用户的权限),您可能需要替代解决方案,例如 Auth0 Fine-Grained Authorization

如果令牌在Authorization头部中发送,跨源资源共享 (CORS) 将不会成为问题,因为它不使用 cookie

下图展示了如何获取 JWT 并用于访问 API 或资源:

![[Pasted image 20230728233134.png]]

  1. 应用程序或客户端向授权服务器请求授权。这是通过不同的授权流程之一执行的。例如,典型的 OpenID Connect/oauth/authorize兼容 Web 应用程序将使用 授权代码流通过端点。
  2. 授权后,授权服务器将访问令牌返回给应用程序。
  3. 应用程序使用访问令牌来访问受保护的资源(例如 API)。

请注意,使用签名令牌时,令牌中包含的所有信息都会向用户或其他方公开,即使他们无法更改它。这意味着您不应将秘密信息放入令牌中。

为什么我们应该使用 JSON Web Token

我们来谈谈JSON Web Token (JWT)Simple Web Token (SWT)Security Assertion Markup Language Tokens (SAML) 相比的优势。

由于 JSONXML 更简洁,因此在编码时其大小也更小,使得 JWTSAML 更紧凑。这使得 JWT 成为在 HTMLHTTP 环境中传递的不错选择。

从安全角度来看,SWT 只能使用 HMAC 算法通过共享密钥进行对称签名。但是,JWTSAML 令牌可以使用 X.509 证书形式的公钥/私钥对进行签名。与签名JSON的简单性相比,在不引入模糊安全漏洞的情况下使用XML数字签名对XML进行签名是非常困难的。

JSON 解析器在大多数编程语言中都很常见,因为它们能够直接映射到对象中。相反,XML 并不能直接映射到对象中。这使得使用 JWT 比使用 SAML 断言更容易。

关于使用,JWT 用于互联网规模。这凸显了在多个平台(尤其是移动平台)上客户端处理 JSON Web Token 的简便性。

![[Pasted image 20230728235737.png]] 编码的 JWT 和编码的 SAML 的长度比较

如果您想了解有关 JSON Web Token 的更多信息,甚至开始使用它们在自己的应用程序中执行身份验证,请浏览至Auth0 处的 JSON Web 令牌登录页面

JWT 怎么使用

参考