-
什么是JWT?
JSON Web Token (JWT) 是一个开源标准(RFC 7519)定义了一种紧凑且自成体系的方式用来在各方之间作为JSON对象安全传输信息。由于此信息是经过数字签名的,因此可以被验证和信任。JWTs 可以使用一个加密算法或者是使用 RSA或者 ECDSA 的公钥/私钥进行认证。
尽管可以对JWT进行加密,以在各方之间提供保密性,我们也可以使用签名令牌。签名令牌可以验证其中声明的完整性,同时加密的token不会与第三方共享声明。当token使用公钥/私钥时,签名也会验证只有私钥的一端。 -
什么时候使用JSON Web Tokens?
以下是一些适用的使用场景:
鉴权: 是JWT最常见的使用场景。一旦用户登陆,每个后续的请求就会包含JWT,允许带有token的用户访问路由,服务和资源。因其低开销并且能够在不同域中轻松使用,使用JWT进行单点登陆成为了当下一项广泛应用的功能。
信息交换:
JWT是在不同用户间安全传输信息很好的方式。因为JWTs可以签名。例如,使用公私钥-你可以确定发信息的人就是他们本人。此外,由于签名计算时使用了header和payload,你也可以验证其中的内容使用被篡改过。
- JWT的结构是什么样子?
在其紧凑的形式中,JWT是由三部分组成,由(.) 进行分割:
包括 Header Payload Signature 因此, 一个 常规的JWT长这样:aaaaaa.bbbbbbb.ccccccc
现在我们分解各个部分:
Header
头部包含两部分:
token的类型,是JWT或者签名算法用到的
例如:
{
"alg": "HS256",
"typ": "JWT"
}
然后,此JSON被Base64Url编码以形成JWT的第一部分。
Payload
token的第二部分是包含声明的payload,包含有关实体(通常是用户)和其他数据的声明。有三种类型的声明:注册声明,公共声明和私有声明。
注册声明:
是一系列预先定义的声明,只是推荐的并非必须,用于提供一系列有用的,可交互操作的声明。其中一部分是: iss (issuer), exp (expiration time), sub (subject), aud (audience),还有等等。
公共声明:
公开声明:使用JWT的人员可以随意定义这些声明。但是为避免冲突,应在IANA JSON Web令牌注册表中定义它们,或将其定义为包含抗冲突命名空间的URI。
私有声明:
这些是自定义声明,旨在在同意使用它们的各方之间共享信息,它们既不是注册声明也不是公共声明。
比如:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
payload作为JWT的第二部分,是经过编码后的base64URL。
注意: 对于已签名的令牌,此信息尽管可以防止篡改,但任何人都可以读取。不要在payload或者header中放置隐私信息除非它已经被加密。
签名
要创建签名部分,必须使用编码后的header,编码后的payload,一个密钥,具体的算法并签名。
如果你想要使用HMAC SHA256 算法,要这样创建签名:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
签名用于验证信息在过程中没有被篡改,并且,对于使用私钥签名的令牌,它还可以验证JWT的发送者是它所指的那个用户。
把它们组合起来
输出是三个 Base64-URL 字符串,通过(.)分割,能够在html和http环境中传递,与SAML等基于XML的标准相比,它更加紧凑。
如果你想要使用JWT并且把这些概念付诸实践,你应该使用 jwt.io debugger 解码,验证,并生成JWTs.
How do JSON Web Tokens work?
在身份验证中,当用户使用其凭据成功登录时,将返回JSON Web令牌。由于令牌是凭据,因此必须格外小心以防止安全问题。总体来说,你应该在尽可能短的时间内持有token。
同样你不应该将敏感session数据存在浏览器存储中,因为这不安全。
每当用户想要访问受保护的路由或资源时,用户代理应该发送JWT,通常是使用Bearer模式在Authorization header中发送。header的内容应该是这样:
Authorization: Bearer <token>
在特定的情况下,这应该是一个无状态的认证机制。服务端受保护的路由会检查Authorization header中JWT的合法性, 如果存在的话,用户将会被允许访问受保护的资源。如果JWT包含必要的信息,去数据库执行特定的查询操作的频率将会降低,尽管不总是这样。
如果token是被发送给Authorization header,不会有跨域共享问题,因为它不使用cookies。
下图展示了一个JWT是如何实现的并且被用于访问API或资源。
- 应用或者客户端请求鉴权服务器鉴权,由不同的授权流程之一执行此操作。比如,一个典型的 OpenID连接兼容程序可以使用授权代码流通过oauth / authorize端点。
- 鉴权完成后,鉴权服务器给应用返回一个访问令牌。
- 应用使用鉴权令牌去访问受权限保护的资源(比如api)。
请注意,带签名的令牌所包含的信息都是暴露给用户或第三方的,尽管它们不能够修改,但最好不要把隐私信息放到令牌中。
为什么要使用JWT?
那我们需要说一说JWT相比简单的网站令牌(SWT)和安全声明标记语言令牌(SAML)的好处。
因为JSON要比XML简短,编码后的体积更小,使得JWT比SAML的兼容性更好,因此在html或者http环境下使用JWT是个很好的选择。
在安全方面,SWT只能由共享机密对称地签名。但是,JWT和SAML令牌可以使用X.509证书形式的公用/专用密钥对进行签名。与签署JSON7的简单性相比,使用XML Digital Signature签署XML而不引入模糊的安全漏洞是非常困难的。
在大多数编程语言中 JSON直接解析为对象是非常普遍的。相反的,XML没有文档到对象的天然映射。因此使用JWT要比SAML断言更容易。
关于用法,JWT是在Internet规模上使用的。 这突显了在多个平台(尤其是移动平台)上对JSON Web令牌进行客户端处理的简便性。