1.什么是JWT?
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。
一句话就是,jwt就是一个有格式定义的字符串,久而久之形成的一个规范。
2.JWT长什么样?
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIGluZm8iLCJpc3MiOiJqd3RsZWFybiIsImV4cCI6MTU4MjgyNzg1OCwidXNlcm5hbWUiOiJhZG1pbiJ9.DJ-tUrH90F_wT0M6DBhnmw4b_DVFBsKUUIUHjSBU-ew
就长上面这个鬼样,浏览器与服务端传递的就是这个玩意;但注意这个字符串包含三个".",其意义在于jwt串是由三部分组成的,那是如何组成这个字符串的呢?
3.JWT的结构
典型的JWT由三个部分组成,每个部分由一个点(.)分隔。
- Header
- Payload
- Signature
header.payload.signature
下面分别介绍这三部分的意义:
Header(头部)
头部包含所使用的签名算法(alg)和令牌的类型(typ),这部分会被编码为Base64URL格式
{
"alg": "HS256", //签名算法
"typ": "JWT" //令牌类型
}
Base64URL编码后的格式:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
Payload(载荷)
Playload包含实际要传输的信息,附带一些其他信息如过期时间、发行时间等。JWT指定了一些官方字段(claims)备用:
- iss: 签发人
- exp: 过期时间
- iat: 签发时间
- nbf: 生效时间
- jti: 编号
- sub: 主题
- aud: 受众
{
"iss":"admin",
"sub": "1234567890",
"name": "John Doe"
}
除了官方字段,在这个部分还可以添加私有字段;
Base64URL编码后的格式:
MiOiJqd3RsZWFybiIsImV4cCI6MTU4MjgyNzg
Signature(签名)
要创建签名部分,必须采用编码的Header,编码的Payload,秘钥,Header中指定的算法,并对其进行签名。
例如,如果要使用HMAC SHA256算法,将按以下方式创建签名:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
签名信息:
DJ-tUrH90F_wT0M6DBhnmw4b_DVFBsKUUIUHjSBU-ew
然后将三部分组合用“.”分割形成了最终的jwt token串
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.MiOiJqd3RsZWFybiIsImV4cCI6MTU4MjgyNzg.DJ-tUrH90F_wT0M6DBhnmw4b_DVFBsKUUIUHjSBU-ew
如何应用JWT?
浏览器接收到服务器发过来的jwt后,可以存储在Cookie或localStorage中。
之后,浏览器每次与服务器通信时都会带上JWT。可以将JWT放在Cookie中,会自动发送(不跨域),或将JWT放在HTTP请求头的授权字段中;
具体流程如下:
1.浏览器发起登录请求
2.服务端验证登录信息是否正确,如果正确创建jwt token
3.服务端将jwt token 返回给浏览器
4.浏览器再次请求服务端时,将jwt token设置在请求头中
5.服务端验证jwt token是否正确,如果正确返回该用户的用户信息