Session共享问题有以下几种方案:
- Session复制,session发生变化,集群中的服务器将会进行同步
- 牵一发而动前身,某个session发生变化,所有服务器都要进行同步
- 集群机器数量大或者用户数量大时,同步的网络开销也就越大
- 每台服务器都含有session,造成数据冗余,资源浪费
- Session集中存储
- 实现简单,无需依赖应用层
- 可以通过重写HttpSession、或者Tomcat的Session机制,来实现无侵入的Session共享
- 通常使用Redis作为存储引擎
- 基于Cookie机制
- 生成Token,写入Cookie中,每次请求浏览器将会带着Token到服务端
- 服务端根据Token识别用户的状态
- 此方式实现简单、不影响服务端性能,但是具有安全问题
基于Cookie机制
JWT
jwt是一种令牌机制,目前共有两种令牌类型:
- 透明令牌
- By Reference Token
- 随机字符串,无法猜测,严格服务器集中校验
- 自包含令牌
- By Value Token
- 可以包含用户元数据或者声明(claims),无状态校验
- 如,JSON Web Token
JSON Web Token,是客户端和服务端信息安全传递以及身份认证的一种解决方案。JWT由三个部分组成:
- header
- playload
- signature
所以,JWT的格式通常如下:
xxxxx.yyyyy.zzzzz
// 比如
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header:
{
"alg": "HS256", // 使用的签名算法
"typ": "JWT" // token的类型
}
此部分经过Base64编码称为JSON Web Token的第一部分。
Payload:
Payload可以称为载荷,用于承载具体的数据,包含实体数据。其中包含claims,是对数据的声明,共有三种类型:
- Registered claims:已注册Claims,是一组预定义的声明,非强制,但是不强制使用。包含 iis(发行人)、exp(到期时间)、sub(主题)、aud(观众)等。
- Public claims:由使用JWT的人随意定义。
- Private claims:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
然后,Payload经过Base64Url编码,形成JSON Web Token 的第二部分。
Signature:
生成签名,由 encode header . encode payload使用header的alg签名算法与指定的secret进行签名。从而保证信息不被篡改、发件人是否属实。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
认证流程
- 客户端登录、服务端生成Token
- 服务端将Token返回给客户端,客户端存储Token到Cookie或者localstorage中
- 客户端携带token调用api,校验token并处理响应
- 为了保证Token的有效性,需要制定Token刷新机制
JWT 优劣
优点:
- CORS
- 不需要CSRF保护
- 无状态校验
- 不需要分布式存储
- 减少服务器压力
缺点:
- 信息公开可见
- 易受XSS攻击
- 可能包含过期授权信息
- 令牌大小随信息量增长
- 无状态与吊销互斥
如果需要更严格的方式,需要使用透明令牌+集中校验的方式。