JSON Web Token
在现在的前后端分离的开发方式中,通常都是用token的方式来进行鉴权,校验用户登录状态。这个就是JSON Web Token (JWT) ,它是一个基于JSON的开放标准 (RFC 7519),它定义了一种紧凑且自包含的方式,使用 JSON 对象在各方之间安全地传输信息。此信息可以验证和信任,因为它是数字签名的。 JWT 可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的 公钥/私钥对 进行签名。特别适用于分布式站点的单点登录(SSO)场景。
JWT是由三段信息构成的,头部,载荷,签名。header.payload.signature
, 将这三段信息文本用.链接一起就构成了Jwt字符串。
eyJhbGciOiJIUzI1NiIsIlR5cGUiOiJKd3QiLCJ0eXAiOiJKV1QifQ.eyJsb2dpbklkIjoyMDIxMDMyNTAwMDAwMDA1LCJleHAiOjE2ODU1ODU0NDN9.4GvPyszmSsTsUWfayQY_KFmXdAZKiivRCwQVLQlSyYE
头部通常由两部分组成:令牌的类型,即 JWT,以及正在使用的签名算法,例如 HMAC SHA256 或 RSA。
{
"alg": "HS256",
"typ": "JWT"
}
这个头部被Base64Url
编码以形成 JWT 的第一部分。
载荷是存放有效信息的地方,有效信息包含三部分,标准中注册的声明,公共的声明,私有的声明。
{
"iss":"http://pigear.com", //签发者
"aud":"http://pigear.com", //jwt所面向的用户
"iat":$nowtime, //签发时间
"nbf":$nowtime + 10, //在什么时间之后该jwt才可用
"exp":$nowtime + 600, //过期时间-10min
"data":{
userId: 1,
avatar: 'http://xx.com/avatar.jpg',
isAdmin: 1
}
}
标准中注册的声明:
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.
私有的声明 :
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
对载荷进行base64加密,得到Jwt的第二部分。
jwt的第三部分是一个签名信息,这个签名信息由三部分组成:
header (base64后的)+'.'+payload (base64后的)+'.'+secret(密钥KEY)
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
密钥KEY是保存在服务器端的,jwt的签发生成也是在服务器端的,密钥KEY就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该泄露出去。
如何使用?
通常在登录操作的时候,服务端校验登录成功后,生成token返回给前端。前端拿到token就存在本地缓存里,后续每次请求接口的时候,就在请求头里加上token。服务端在拿到token后进行解密校验,校验通过,就可以直接使用载荷里的字段值,进行后续的操作。不用像session方式还要在服务端存储。