JSON Web Token (JWT)
JWT的全名是 JSON Web Token,是一种基于 JSON 的开放标准(RFC 7519),它定义了一种简洁(compact)且自包含(self-contained)的方式,用于在双方之间安全地將信息作为 JSON 传输。而這个信息是經過数字签名(Digital Signature),因此可以被验证及信任。可以使用 密码(经过 HMAC 演算法) 或用一對 公钥/私钥(经过 RSA 或 ECDSA 演算法) 來对 JWT 進行签章。
什么情况下使用JWT
- 授权(Authorization) :这是很常见 JWT 的使用方式,例如使用者从 Client 端登入后,该使用者再次对 Server 端发送请求的時候,會夹带著 JWT,允许使用者存取该 token 有权限的资源。单点登录(Single Sign On)是当今广泛使用 JWT 的功能之一,因為它的成本较小并且可以在不同的域(domain)中轻松使用。
- 信息交换(Information Exchange) :JWT 可以透过公钥/私钥來做签章,让我们可以知道是谁发送这个 JWT,此外,由于签章是使用 header 和 payload 计算的,因此还可以验证內容是否遭到篡改。
JWT 的組成
- Header
- Payload
- Signature/encryption data
由Header(头部)、Payload(负载) 、Signature(签名) 三部分组成,中间用点"."隔开。
格式:Header.Payload.Signature
示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0MzMiLCJpYXQiOjE1MTYyMzkwMjJ9.6DPnEsDK3HABz5RNmK89WIlxPWEras-2qTbTpOIVJxg
Header
Header是一个Json对象,用于描述JWT的元数据。
{
"alg":"HS256",
"typ":"JWT"
}
alg是签名使用的算法,typ是token的类型。JWT的token类型统一为JWT.
Payload
Payload也是一个JSON对象,用于存储传递的数据。
JWT规定了7个标准的字段,同时也可以存储自定义字段。
jwt框架都会根据exp判断token是否有效。
{
"iss":"签发人",
"exp":"token过期时间",
"sub":"主题",
"aud":"受众",
"nbf":"生效时间",
"iat":"签名时间",
"jti":"编号"
"username":"这是一个自定义字段"
}
Signature
Signature是对Header和Payload的签名,防止数据被篡改。
需要使用一个密钥来进行签名,密钥都是由服务器来保管。
先将Header和Payload都使用Base64URL编码。
然后按照Header中的算法进行对Base65URL编码后的Haeder和Payload进行签名,最后将三部分用"."连接起来,组成最终的token。
使用方式
客户端发送登录请求,服务器验证用户并生成token,返回给客户端。
客户端在其他请求时带上这个token,每次服务器都会解析token,判断用户身份。
客户端一般将token放在HTTP请求头的Authorization字段中。
示例:Authorization Bearer token
适合多点同时登录一账号,比如多个服务有不同的系统,不用每个系统都登录一遍。不适合单账号同时只能在一个地方登录。
因为JWT默认不加密,可以在生成token后,对token再次加密。
通常都是配合HTTPS,更安全。
为了减少盗用,过期时间应该设置短一点,并且使用HTTPS传输。