JSON Web Tokenv由三部分组成,它们之间用点 . 连接。这三部分分别是:
完整 JWT 结构如下:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTYxNDIzMDIsInVzZXJuYW1lIjoiamFjayJ9.l9kjzYelZJXrD7MxKhR2p3vjcEi6JBsmPVY9uxmG2zY
JWT 的头部包含两部分信息:
{
'typ': "JWT",
'alg': "HS256"
}
最后,用 Base64URL 对这个 JSON 对象编码就得到 JWT 的第一部分。
Payload 部分用来存放业务需要传递的数据。JWT 规定了7个官方字段,供选用。
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。
{
"sub": "1234567890",
"name": "jiang",
"iat": 1516239022
}
注意,JWT 默认是不加密的,任何人都可以读到,所以不要把敏感信息(密码,手机号等)放在这个部分。
最后,用 Base64URL 对这个 JSON 对象编码就得到 JWT 的第二部分。
Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个 密钥(secret),这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。
Header 和 Payload 编码采用的是 Base64URL。这个算法跟 Base64 算法基本类似,但有一些小的不同。
JWT 作为一个令牌(token),有些场合可能会放到 URL中(比如 api.example.com/?token=xxx)。
Base64 编码有三个字符 +、/ 和 =,在 URL 里面有特殊含义,所以要被替换掉:= 被省略、+ 替换成 -,/ 替换成 _ 。这就是 Base64URL 算法。
如果需要在 URL 中携带 JWT,secret 也需要使用 Base64URL 编码。具体看官网演示:
https://jwt.io/
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
Authorization: Bearer jwt
另一种做法是,跨域的时候,JWT 就放在 POST 请求的数据体里面。
优点:
缺点:
一个 JWT(JSON Web Token)由三部分构成,这些部分之间用点 (.) 分隔:
Header(头部):包含 token 的元数据,如 token 类型和使用的哈希算法等信息。
Payload(载荷):包含所要传递的数据,也称为 claims。这些 claims 既可以是预定义的,也可以是自定义的。例如,在你的代码中,你添加了一个名为 "username" 的 claim,并将其值设置为 "jack"。
Signature(签名):用于验证消息的发送者是否是其声称的发送者,并保证消息在传输过程中没有被篡改。签名的生成方法是:先对 header 和 payload 分别进行 Base64Url 编码,然后将它们连接在一起,最后用指定的 secret 和哈希算法对其进行哈希处理。
所以,一个 JWT token 的形式是:
header.payload.signature
这三部分都是 Base64Url 编码的,因此 JWT 是一个可直接在 URL、header 和各种其他地方传输的字符串。