JSON Web Token(JWT)简介

什么是JWT

JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公用/专用密钥对对JWT进行签名。

尽管可以对JWT进行加密以在各方之间提供保密性,但我们将重点关注已签名的令牌。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌则将这些声明隐藏在其他方的面前。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。

–摘自官网

使用场景

web应用中,服务器使用session存储一些用户信息,在用户第一次请求时,会生成一个session,并将sessionId返回给客户端,存储到cookie中。下一次请求时,携带cookie,服务器就能知道当前请求的是哪一个用户。
在分布式或集群中,如果使用session作为用户的标识,服务A与服务B不在同一个web服务器中,这个时候需要使用session共享,如果用户量越来越多,session也会更多,加大了服务器的压力。
这个时候就可以使用JWT作为解决方案,用户请求时生成一个token,返回给前端,客户端每次请求时携带token进行访问,服务器校验token即可。

JWT结构

JWT以紧凑的形式由三部分组成,这些部分由点(.)分隔,分别是:

  • 头部(Header)
  • 有效载荷(Payload)
  • 签名(Signature)
1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

头部通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法,例如HMAC SHA256或RSA。

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}

然后,此JSON使用Base64Url编码生成JWT的第一部分

Payload

官方提供了7个字段(建议但不强制使用)

  • iss 发布者
  • sub 主题
  • aud 受众群体
  • exp 过期时间
  • nbf 生效时间
  • iat 签发时间
  • jti 编号

除了官方提供的字段,也可以使用自己的字段,不建议填写敏感字段。

1
2
3
4
5
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}

然后,此JSON使用Base64Url编码生成JWT的第二部分

Signature

首先需要一个密钥(secret),这个密钥保存在服务端的,secret不能泄漏,secret是签发和验证JWT的。
然后按照Header中设定的算法进行加密,如果使用HMAC SHA256算法,则将通过以下方式创建签名:

1
2
3
4
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

最后将算出的三个部分使用.分割组成一个token

使用

客户端收到服务端返回的token后,将token保存起来,每次请求时携带token。
一般放到请求头中Authorization中,并标注Bearer

1
Authorization: Bearer <token>