JWT令牌介绍

376 阅读5分钟

什么是JWT

JSON Web令牌(JWT)是一个开放标准,它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以进行验证和信任。可以使用密钥(使用HMAC算法)或使用RSAECDSA的公钥/私钥配对对JWT进行签名。

尽管可以对JWT进行加密以提供双方之间的保密性,但我们将重点关注已签名的令牌。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌则对第三方隐藏这些声明。当使用公钥/私钥对对令牌进行签名时,签名还可以证明只有持有私钥的一方才是对其进行签名的一方。

什么时候使用JWT

  • 授权:这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单点登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。

  • 信息交换:JSON Web令牌是在各方之间安全地传输信息的好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确保发件人是他们所说的人。此外,由于签名是使用headerpayload计算的,因此您还可以验证内容是否遭到篡改。

JWT的结构

JSON Web令牌以紧凑的形式由三部分组成,这些部分由点(.)分隔,分别是:

  • 标头
  • 有效载荷
  • 签名

因此,JWT通常如下所示。

xxxxx.yyyyy.zzzzz

让我们分解不同的部分。

标头

标头通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法,例如HMAC SHA256RSA

例如:

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

然后,此JSON被Base64Url编码,形成JWT的第一部分。

有效载荷

令牌的第二部分是有效负载payload,这部分里包含声明。声明是有关实体(通常是用户信息)和其他数据的声明。声明有以下三种类型:registered, public, private

  • registered:这些是一组非强制性的但建议使用的预定义的声明。其中一些是: iss(发出者), exp(到期时间), sub(subject), aud(audience)等。

请注意,声明名称仅是三个字符,因为JWT是紧凑的。

  • public:使用JWT的人员可以随意定义这些声明。但为避免冲突,它们应该在IANA JSON Web Token Registry 已被定义,或将其定义为不会冲突的名称URI。

  • private:这些是自定义声明,被用来在同意使用它们的各方之间分享信息,同时即非public又非registered。

有效负载示例可能是:

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

然后,对payload进行Base64Url编码,以形成JWT的第二部分。

请注意,对于已签名的令牌,此信息尽管可以防止篡改,但任何人都可以读取。除非将其加密,否则请勿将机密信息放入JWT的有效负载或标头中。

签名

要创建签名部分,您必须获取编码的标头(header),编码的有效载荷(payload),密钥(serect),标头中指定的算法,并对其进行签名。

例如,如果要使用HMAC SHA256算法,则将通过以下方式创建签名:

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

签名用于验证消息在此过程中没有被篡改过,并且对于使用私钥进行签名的令牌,它还可以验证JWT的发件人是谁。

放在一起

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

下图显示了一个JWT,它已对先前的标头和有效负载进行了编码,并用一个秘密进行了签名。

JWT如何工作

在身份验证中,当用户成功登录时,将返回JSON Web令牌。由于令牌是凭据,因此必须格外小心以防止安全问题。通常,令牌的保留时间不应超过要求的时间。

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

每当用户想要访问受保护的路由或资源时,User agent 需要发送JWT令牌,通常在Authorization头部使用Bearer语法 。标头的内容应如下所示:

Authorization: Bearer <token>

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

如果令牌是在Authorization标头中发送的,则跨域资源共享(CORS)不会成为问题,因为它不使用cookie。

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

  1. 应用程序或客户端向服务器请求授权。
  1. 授予授权后,授权服务器会将访问令牌返回给应用程序。
  2. 该应用程序使用访问令牌来访问受保护的资源(例如API)。

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

JWT的好处

Simple Web Tokens (SWT)and Security Assertion Markup Language Tokens (SAML)相比:

  • 尺寸: 更小,更紧凑
  • 安全: JWT和SAML令牌可以使用X.509证书形式的公用/专用密钥对进行签名, 而且对JSON签名比XML更简单
  • 简单:JSON直接映射对象,比XML断言更简单
  • 用法:用法更简单,在多平台(如移动端)使用JWT更方便