前言
日常开发中,客户端与服务器通常采用HTTP协议进行通信,但HTTP是没有状态的,无法记录用户的身份信息和行为。
会话跟踪技术是一种在客户端与服务器间保持HTTP状态的解决方案,我们所熟知的有Cookie + Session、URL重写、Token等。
Cookie在浏览器保存SessionID、Session实际内容保存在服务端,目前的项目都是前后端分离 + 微服务,所以会面临Session共享问题,随着用户量的增多,开销就会越大。URL重写又是通过明文传输,不安全容易被劫持。
Token的优势:
- Token支持跨域访问,Cookie不可以跨域访问。
- Token支持多平台,Cookie只支持部分web端。
What is JWT ?
JWT的全称是Json Web Token,是一种基于JSON的、用于在网络上声明某种主张的令牌(token)规范。
官方解释:
JWT由三部分组成:hand、payload、signature,各部分通过 ‘ . ’ 连接
xxxx . yyyy . zzzz
1、HEAD
头部是一个JSON对象,存储描述数据类型(JWT)和签名算法(HSA256、RSA256),通过Base64UrlEncode编码后生成head 。
编码:
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9
解码:
{
"alg": "RS256",
"typ": "JWT"
}
2、PAYLOAD
负载存放一些传输的有效声明,可以使用官方提供的声明,也可以自定义声明。同样通过Base64UrlEncode编码后生成payload。声明可以分为三种类型:
- Registered claims:
官方预定义的、非强制性的但是推荐使用的、有助于交互的声明(注意使用这些声明只能是三个字符)。
名称 | 作用 |
---|---|
iss (issuer) | 签发人 |
sub (subject) | 主题 |
aud (audience) | 受众 |
exp (expiration time) | 过期时间 |
nbf (Not Before) | 生效时间 |
iat (Issued At) | 签发时间 |
jti (JWT ID) | 编号 |
-
Public claims:
保留给JWT的使用者自定义。但是需要注意避免使用IANA JSON Web Token Registry中定义的关键字。 -
Private claims:
保留给JWT的使用者自定义,用来传送传输双方约定好的消息。((—_—)是不是没搞懂public claims和private claims的区别,阿浪也不知道)
编码:
eyJhdWQiOiLopb_pl6jpmL_mtaoiLCJkYXRhIjoiXCLopb_pl6jpmL_mtapcIiIsImlzcyI6IkhBTkdIVUFfQURNSU4iLCJleHAiOjE2MjIzNjA4NDEsImlhdCI6MTYyMjM2MDg0MX0
解码:
{
"aud": "西门阿浪",
"data": "\"西门阿浪\"",
"iss": "HANGHUA_ADMIN",
"exp": 1622360841,
"iat": 1622360841
}
3、SIGNATURE
数据签名是JWT的核心部分,构成较为复杂,且无法被反编码。
HS256加密:
signature = HMACSHA256( base64UrlEncode(header) + "." +base64UrlEncode(payload), secret );
RS256加密:
signature = RSASHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload), publicKey, privateKey)
signature可以选择对称加密算法或者非对称加密算法,常用的就是HS256、RS256。
-
对称加密: 加密方和解密方利用同一个秘钥对数据进行加密和解密。
-
非对称加密: 加密方用私钥加密,并把公钥告诉解密方用于解密。
4、JWT执行逻辑
逻辑清晰明了,用户首次登陆时,通过传输账号密码验证身份,验证成功后,服务器生成Token响应用户。用户后续请求只需要传送Token,服务器只需对Token进行校验来确认身份。
双Token 保证 活跃用户
活跃用户
Token用于身份认证时,如果有效期设置太长,泄露了会不安全。如果设置太短,用户频繁的重新登陆,程序员的祖坟有可能不保。那如何界定有效时间呢?这就要引入一个概念:用户的活跃性。
系统把用户分为活跃用户和不活跃用户,对于不活跃用户,token过期后需要重新登陆,因为使用频率较低,token失活后重新登陆,他的感受没有那么强烈。
活跃用户在token过期后,不应该直接登陆,而是要根据他的活跃时间来判定是否重新激活token,当符合条件时,直接激活Token,带给用户最好的体验。
若token有效期时长为at,活跃用户时长计为rt,且用户每次操作客户端后活跃时间都与之同步刷新。
<