【Sa-Token 中 三种Session会话 模型详解】
前言
说到 Session,很多人第一反应可能就是 JSP 中的 HttpSession
。它的工作机制大致如下:
当客户端首次与服务器建立连接时,服务器会为其分配一个 唯一的 ID 作为身份标识,并将该 ID 写入到 Cookie 中。此后,客户端每次请求时都会携带这个 ID,服务器则根据该 ID 找到对应的 Session 对象,从而维持会话状态。
这种机制实现简单,但也存在不少明显的缺陷:
- 多端登录隔离:同一账号如果分别在 PC 和 APP 登录,会被识别为两个互不关联的会话。
- 账号隔离限制:一个设备往往难以同时维持多个账号的登录状态。
- 会话浪费:每当有新的客户端访问,哪怕只是请求一次页面,服务器都会新建一个 Session 对象,造成资源浪费。
- 对 Cookie 的依赖:在某些不支持或禁用 Cookie 的客户端环境下,这种机制会直接失效。
Sa-Token官网:https://sa-token.cc/doc.html#/
SaToken 主要操作三种Session结构类:
SaTokenDaoDefaultImpl:
里面的成员变量 dataMap 主要存放内容:
- Account-Session:
- key:
this.getConfigOrGlobal().getTokenName() + ":" + this.loginType + ":session:" + loginId
- value:Account-Session对象
- key:
- Token-Session:
- key:由token生成的连接字符串
- value:Token-Session对象
- Custom-Session:
- key:由自定义的 SessionId 生成的连接字符串
- value:Custom-Session 对象
Sa-Token 中三种 Session 会话模型详解
在权限认证框架中,Session 是非常核心的概念,Sa-Token 作为一款国人开发的轻量级权限认证框架,对 Session 的抽象和扩展非常灵活。理解 Sa-Token 的三种 Session 模型,对于我们合理管理用户会话、权限和业务数据都非常重要。
本文将详细讲解 Sa-Token 中的三种 Session 模型:
- Account-Session(用户会话)
- Token-Session(令牌会话)
- Custom-Session(自定义会话)
并结合场景给出实际应用案例,帮助你快速掌握这些概念。
1. Account-Session(用户会话)
定义
Account-Session 以用户 ID 作为唯一标识,绑定该用户全局会话相关的数据。一个用户无论在多少终端、多少 Token 登录,User-Session 都是唯一的。
特点
- Sa-Token只在调用StpUtil.login(id)登录会话时才会产生Session,不会为每个陌生会话都产生Session,节省性能。
- 在登录时产生的Session,是分配给账号id的,而不是分配给指定客户端的,也就是说在PC、APP上登录的同一账号所得到的Session也是同一个,所以两端可以非常轻松的同步数据。
- Sa-Token支持Cookie、Header、body三个途径提交Token,而不是仅限于Cookie。
- 由于不强依赖Cookie,所以只要将Token存储到不同的地方,便可以做到一个客户端同时登录多个账号。
应用场景
- 跨设备共享用户信息
- 用户同时在手机、PC 登录,只要修改了头像/昵称,这些信息需要所有设备立即同步,存在 Account-Session 中就能做到全局一致。。
使用示例
// 获取用户会话 ,这个可以看一下原理
SaSession session = StpUtil.getSession();// 存数据
session.set("nickname", "小明");// 取数据
String nickname = session.getString("nickname");
底层源码token 生成:
public String createLoginSession(Object id, SaLoginModel loginModel) {this.checkLoginArgs(id, loginModel);SaTokenConfig config = this.getConfigOrGlobal();loginModel.build(config);String tokenValue = this.distUsableToken(id, loginModel);SaSession session = this.getSessionByLoginId(id, true, loginModel.getTimeoutOrGlobalConfig());session.updateMinTimeout(loginModel.getTimeout());TokenSign tokenSign = new TokenSign(tokenValue, loginModel.getDeviceOrDefault(), loginModel.getTokenSignTag());session.addTokenSign(tokenSign);this.saveTokenToIdMapping(tokenValue, id, loginModel.getTimeout());if (this.isOpenCheckActiveTimeout()) {this.setLastActiveToNow(tokenValue, loginModel.getActiveTimeout(), loginModel.getTimeoutOrGlobalConfig());}SaTokenEventCenter.doLogin(this.loginType, id, tokenValue, loginModel);if (config.getMaxLoginCount() != -1) {this.logoutByMaxLoginCount(id, session, (String)null, config.getMaxLoginCount());}return tokenValue;}
主要通过distUsableToken()
方法,并基于loginId生成一个新的token(这个token和这个id有对应的映射关系),然后通过请求头head携带到对应的前端,后续前端都是通过这个token来获取对应的loginid,得到 sasession
生成的key
使用Redis:生成的key - value
satoken:login:session:10001:存放的是对应的login的session存放的数据。
satoken:login:token:xxxx:存放的是这个token的值xxxx,和对应loginId的映射
2. Token-Session(令牌会话)
定义
Token-Session 是以 Token 值为唯一标识的会话模型。每个 Token 登录都会对应一个独立的 Token-Session。
特点
- 与 Token 一一对应,不同 Token 对应不同的 Session。
- 在多端同时登录时,不同终端的 Token-Session 是相互独立的。
- 适合存储与“某次登录会话”相关的信息,比如设备信息、登录位置、单点登录数据等。
使用示例
// 获取当前 Token 对应的会话
SaSession tokenSession = StpUtil.getTokenSession();// 存数据
tokenSession.set("device", "Android");// 取数据
String device = tokenSession.getString("device");
应用场景
- 移动端和 Web 端需要存储不同的上下文信息。
- 多设备管理时,区分每个登录设备的状态。
3. Custom-Session(自定义会话)
定义
Custom-Session 是 Sa-Token 提供的 任意自定义 key 的会话模型,可根据业务需要灵活创建。
特点
- 以业务自定义的 key 为唯一标识。
- 不依赖用户 ID 或 Token。
- 更像是一个分布式缓存工具,开发者可以自由创建不同的 Session 空间。
使用示例
// 创建一个 key 为 "shop:1001" 的自定义会话
SaSession shopSession = SaSessionCustomUtil.getSessionById("shop:1001");// 存数据
shopSession.set("shopName", "CSDN 小店");// 取数据
String shopName = shopSession.getString("shopName");
应用场景
- 按业务实体(如商店、项目、部门)维度存储数据。
- 适合做业务隔离,例如一个商城项目中,每个店铺独立存储信息。
4. 三者对比总结
会话模型 | 唯一标识 | 作用范围 | 应用场景 |
---|---|---|---|
User-Session | 用户 ID | 跨端共享的用户全局信息 | 用户昵称、角色权限、配置 |
Token-Session | Token 值 | 单个登录会话 | 登录设备信息、临时上下文 |
Custom-Session | 自定义 key | 任意业务维度 | 店铺信息、项目配置、业务缓存 |
5. 三种session结构图
6. 总结
- User-Session:关注用户全局会话,跨设备共享。
- Token-Session:关注某次具体登录会话,端端隔离。
- Custom-Session:完全业务驱动,随意定义会话维度。
理解并合理使用这三种会话模型,可以让我们在权限认证和业务数据管理上更加游刃有余。无论是做用户中心、设备管理,还是多租户业务,Sa-Token 都能提供强大的支持。