一文精通JWT Token、ID Token、Access Token、Refresh Token
JWT Token
JSON Web Token (JWT,RFC 7519 (opens new window)),是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准((RFC 7519)。该 token 被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 token 也可直接被用于认证,也可被加密。
JWT认证流程
用户认证的流程
- 用户使用账号(手机/邮箱/用户名)密码请求服务器
- 服务器验证用户账号是否和数据库匹配
- 服务器通过验证后发送给客户端一个 JWT Token
- 客户端存储 Token,并在每次请求时携带该 Token
- 服务端验证 Token 值,并根据 Token 合法性返回对应资源
JWT Token的标准样式
JWT标准的令牌由三部分组成,这些部分均是URL安全的Base64编码的字符串,并且用点(.
)分隔:
-
Header(头部)
-
Payload(有效载荷)
-
Signature(签名)
因此,一个典型的JWT看起来像这样:
xxxxx.yyyyy.zzzzz
每一部分的详细说明如下:
1. Header
Header通常由两部分组成:令牌的类型(即JWT)和签名使用的算法(如HS256)。例如:
{
"alg": "HS256",
"typ": "JWT"
}
然后将这个JSON对象进行Base64编码,得到Header部分。
2. Payload
Payload包含了要传递的实际声明信息,比如用户的ID、声明的权限、到期时间(exp
)等。例如:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}
这个JSON对象也会被进行Base64编码,形成Payload部分。
3. Signature
Signature部分是对前两部分进行签名的,确保发出的信息未被篡改。它需要使用HEADER中指定的算法来进行计算,并且需要使用一个密钥(只有服务器知道)。具体步骤如下:
- 将HEADER和PAYLOAD的Base64编码值连接起来,用点(
.
)分隔。 - 使用指定的算法(如HS256)和密钥对上述连接的字符串进行签名。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
最终的Signature部分就是这个签名值的Base64编码结果。
如果我们将上面的Header和Payload进行Base64编码,并假设使用了一个密钥来计算出Signature,那么完整的JWT可能看起来像这样:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMH yaJr9inatingTypingThisIntoABrowserIsProbablyAGoodIdea
客户端附带 JWT Token 的方式
用户在完成认证后会返回开发者一个 JWT Token,开发者需将此 Token 存储于客户端,然后将此 Token 发送给开发者受限的后端服务器进行验证。
建议使用 HTTP Header Authorization 的形式携带 Token,以下以 JavaScript 的 axios 库为例示范如何携带:
const axios = require("axios");
axios
.get({
url: "https://yourd