什么是JSON Web Token?
JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,使用JSON对象在各方之间安全地传输信息。此信息可以被验证和信任,因为它是数字签名的。JSON Web Tokens(JWTs)可以使用密钥(通过HMAC算法)进行签名,或者使用公钥/私钥对,采用RSA或ECDSA算法进行签名。
尽管JSON Web Tokens(JWT)可以被加密以在各方之间提供保密性,我们将重点关注签名令牌。签名令牌可以验证其中包含的声明的完整性,而加密令牌则将这些声明隐藏起来,不让其他方看到。当使用公钥/私钥对对令牌进行签名时,签名还证实了只有持有私钥的一方才是签名者。
什么时候应该使用JSON Web Tokens?
以下是JSON Web令牌使用的一些场景:
授权: 这是使用JWT最常见的场景。一旦用户登录,每个后续请求都将包含JWT,允许用户访问路由、服务和资源。单点登录是广泛使用的一项功能,因为它的开销很小,并且能够轻松地在不同领域中使用。
信息交换: JSON Web令牌是一种各方之间安全传输信息的好方法。因为JWT可以被签名,可以确保发送者就是他们所说的那个人。此外,由于签名是使用头部和有效负载计算的,因此您还可以验证内容是否被篡改。
JSON Web Token结构是什么?
JSON Web Tokens由三个部分组成,由点分隔(.),分别为:
Header 【报头】
Payload 【有效载荷】
Signature 【签名】
因此,JWT通常如下所示:
xxxxx.yyyyy.zzzzz
让我们分解一下这些部分:
Header
标头通常由两部分组成:令牌的类型(JWT)和使用的签名算法(如HMAC SHA 256或RSA)。
举例:
{
"alg": "HS256",
"typ": "JWT"
}
这个JSON是Base64 Url编码的。
Payload
令牌的第二部分是有效载荷,包含声明。声明是关于实体(通常是用户)和附加数据的声明。有三种类型:注册,公共和私有声明。
Registered claims: 这是一组预定义的声明,不是强制性的,推荐使用。提供一组有用的、可互操作的声明。比如:iss(发行者),exp(到期时间),sub(主题),aud(受众)等。
Public claims: 这些可以由使用JWT的人随意定义。但是为了避免冲突,它们应该在IANA JSON Web令牌注册表中定义。
Private claims:这些自定义声明是为了在各方之间共享信息而创建的,既不是注册的也不是公开的声明。
举例:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
对有效负载进行Base64 Url编码,以形成JSON Web令牌的第二部分。
Ps: 对于已签名的令牌,尽管这些信息受到保护,不会被篡改,但任何人都可以读取。不要将秘密信息放在JWT的有效载荷或头部元素中,除非它被加密。
Signature
要创建签名部分,您必须获取已编码的头部、有效负载、头部中指定的算法。
例如,如果你想使用HMAC SHA256算法,签名将按以下方式创建:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
签名用于验证消息在发送过程中没有被沿着更改。并且,在使用私钥签名的令牌的情况下,它还可以验证JWT的发送者是否是它所说的那个人。
组合
最终,输出的是由点分隔Base64-URL字符串,可以在HTML和HTTP环境中轻松传递。同时,与基于XML的标准(如SAML)相比更加紧凑。
下面显示了一个JWT,它具有头部和有效负载编码,并且使用加密签名。
如果您想使用JWT并将这些概念付诸实践,您可以使用jwt.io编译器来解码、验证和生成JWT。
JSON Web Tokens如何工作?
在身份验证中,当用户成功登录后,将返回JSON Web Token。由于令牌是凭证,因此必须非常小心,防止出现安全问题。
由于缺乏浏览器安全性,您还不应将敏感会话数据存储在浏览器中。
每当用户想要访问受保护的路由或资源时,用户发送JWT,通常在使用Bearer模式的Authorization头中设置。标题的内容应该如下所示:
Authorization: Bearer <token>
在某些情况下,可以是一种无状态的授权机制。服务器的protected routes将检查Authorization头中是否存在有效的JWT。如果存在,则允许用户访问受保护的资源。
请注意,如果您通过HTTP标头发送JWT令牌,则应尝试防止它们太大。有些服务器不接受超过8 KB的头文件。如果您试图在JWT令牌中嵌入太多信息,例如包含所有用户的权限,则可能需要替代解决方案,例如:Auth 0 Fine-Grained Authorization
如果令牌在Authorization报头中发送,跨域资源共享(CORS)将不会成为问题,因为它不使用Cookie。
下图显示了如何获取JWT并将其用于访问API或资源:
请注意,使用签名令牌时,令牌中包含的所有信息都会暴露给用户或其他方。这意味着您不应该将机密信息放入令牌中。
为什么要使用JSON Web Tokens?
让我们来讨论一下与简单Web令牌(SWT) 和安全断言标记语言令牌(SAML) 相比,JSON Web令牌(JWT) 的优点。
由于JSON没有XML那么冗长。所以,在编码时,它的大小也更小。这使得JWT比SAML更紧凑。
安全方面,SWT只能通过使用HMAC算法进行对称签名。但是,JWT和SAML令牌可以使用X.509证书形式的公钥/私钥对进行签名。与JSON签名的简单性相比,使用XML数字签名而不引入模糊的安全漏洞是非常困难的。
JSON解析器在大多数编程语言中很常见,因为它们直接映射到对象。相反,XML没有自然的文档到对象的映射。