JWT(JSON WEB TOKEN)是什么
JSON Web Token(JWT)是一种开放标准RFC 7519 ,他定义了一种压缩、独立的JSON对象,可以安全地将信息以JSON对象的形式传递给各方。这个信息可以被验证和信任,因为他是通过数字签名的。JWTs签名可以通过一个私钥(使用HMAC算法)或者使用RSA的公钥/私钥对签名。
首先解释一些概念:
Compact:由于JWT的体积通常较小,所以可以通过URL,POST参数,或者内嵌在HTTP Header.补充说明一点,体积小说明传输更快
Self-contained:JWT通常携带的信息包含了一个用户所有需要的信息,所以不需要再去数据库查询一次。
什么时候应该使用JWT
以下是一些JWT有用的场景:
- 身份验证:这是使用JWT最常见的场景。一旦用户登录,每个后续请求将包括JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用JWT的一个特性,因为它的开销很小,而且它可以很容易地跨不同的域使用。
- 信息交换:JWT是在双方之间安全地传输信息的一种好方法。因为JWTs可以是signed——例如,使用公钥/私钥pairs——您可以确定发送者是他们说的那些人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。
JWT的结构
jwt由三部分组成,各部分之间通过“.” 来划分,分别是一下三部分:
- Header
- Payload
- Signature
所以,JWT的通常格式如下:
xxxxx.yyyy.zzzz
Header
Header通常有俩部分组成,token的类型,通常是JWT,使用的Hash算法,类如HMAC SHA256 或者RSA
下面是一个例子
{ "alg":"HS256", "typ":"JWT" }
Payload
第二部分主要包含了声明。声明是关于实体(通常是用户)和其他元数据的描述。声明有三种类型:注册、公开和私人声明。
- 注册声明:这些是一组预定义的声明,这些声明不是强制性的,而是推荐的,以提供一组有用的、可互操作的声明。其中有些是:iss(发行者)、exp(到期时间)、sub(subject)、aud(受众)以及其他。
注意,只要JWT是压缩的,声明名称就只有三个字符。
- 公共声明:这些可以由使用JWTs的人来定义。但是为了避免冲突,它们应该在IANA JSON Web Token注册表中定义,或者定义为包含一个抗冲突名称空间的URI。
- 私人声明:这些是自定义的声明要求,用于在双方同意使用它们的情况下共享信息,并且没有注册或公开声明。
下面是一个例子
{ "sub":"12345678", "name":"John Doe", "admin":true }
Signature
要创建签名部分,必须使用编码头、编码有效负载、一个秘密、在头中指定的算法,并签名。
例如,如果您想使用HMAC SHA256算法,签名将以以下方式创建:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
组合上面三部分
上面三部分使用Base64 encode,输出是三个Base64字符串,使用点把三个连接在一起,这些点可以很容易地在HTML和HTTP环境中传递,而与像SAML这样的基于xml的标准相比,它们更紧凑。
下面显示了一个JWT,它包含了前面的头文件和有效负载,并与一个秘密签了名。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9. TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
如果您想使用JWT并将这些概念付诸实践,您可以使用JWT.io DEbugger调试器解码、验证和生成JWTs。
JWT 是如何使用
在身份验证中,当用户成功地使用他们的凭证登录时,将返回一个JSON Web Token,并且必须在本地保存(通常在本地存储中,但也可以使用cookie),而不是在服务器中创建会话并返回cookie的传统方法。
当用户想要访问受保护的路由或资源时,用户代理应该发送JWT,通常是在HTTP 头部中的Authorization 使用 Bearer模式。头部的内容应该如下所示:
GET /resource/1 HTTP/1.1 Host: example.com Authorization: Bearer <token>
补充说明一下
在Oauth 2.0 中定义的token接入模式有俩种,一种是Bearer,一种是mac
其中Bearer格式如上面所示,只需简单的在Authorization包含Token即可
而“mac”标记类型定义在i - d .hammer-oauth-v2-mac- token中与访问令牌一起发布一个令牌的秘密
用于在HTTP请求的某些组件上签名:
GET /resource/1 HTTP/1.1 Host: example.com Authorization: MAC token="h480djs93hd8", timestamp="137131200", nonce="dj83hs9s", signature="kDZvddkndxvhGRXZhvuDjEWhGeE="
每个访问令牌类型定义都指定了附加的属性(如果有)与“access_token”响应一起发送到客户端
参数。它还定义了HTTP身份验证方法在创建受保护的资源请求时包含访问令牌。这是一个无状态的身份验证机制,因为用户状态永远不会保存在服务器内存中。服务器的受保护路由将在授权头中检查有效的JWT,如果它存在,用户将被允许访问受保护的资源。由于JWTs是自包含的,所以所有必要的信息都在那里,减少了多次查询数据库的需求。
这允许您完全依赖于无状态的数据api,甚至向下游服务发出请求。哪个域为您的api服务并不重要,因此跨源资源共享(CORS)不会成为一个问题,因为它不使用cookie。
下面显示的是执行的整个流程