Sa-Token登录认证模块深度探索
本文深入探讨了Sa-Token框架的核心登录认证功能,全面解析了StpUtil工具类的API使用方法、多端登录与同端互斥登录的实现机制、会话管理与Token风格定制策略,以及记住我模式与自动续签机制的工作原理。文章详细介绍了各种登录场景的配置方案和最佳实践,为开发者构建安全、灵活的权限认证系统提供了完整的技术指导。
StpUtil核心API使用方法详解
StpUtil是Sa-Token框架的核心工具类,提供了完整的登录认证、权限校验、会话管理等核心功能。作为开发者与Sa-Token交互的主要入口,掌握StpUtil的API使用方法至关重要。
登录认证API
StpUtil提供了多种登录方式,满足不同业务场景的需求:
基础登录方法
// 最简单的登录方式,只需传入用户ID
StpUtil.login(10001);
// 指定设备类型登录,支持多端同时在线
StpUtil.login(10001, "APP");
// 记住我模式,设置持久Cookie
StpUtil.login(10001, true);
// 自定义Token有效期
StpUtil.login(10001, 3600); // 有效期1小时
高级登录配置
通过SaLoginParameter可以精细控制登录行为:
StpUtil.login(10001, new SaLoginParameter()
.setDeviceType("PC") // 设备类型
.setDeviceId("device-12345") // 设备唯一标识
.setIsLastingCookie(true) // 持久Cookie
.setTimeout(604800) // Token有效期7天
.setActiveTimeout(86400) // 活跃检查时间24小时
.setIsConcurrent(false) // 禁止多地登录
.setIsShare(true) // 共享Token
.setMaxLoginCount(5) // 最大登录数限制
.setExtra("login_ip", "192.168.1.1") // 扩展参数
);
会话状态管理
登录状态检查
// 检查是否登录,返回boolean
boolean isLogin = StpUtil.isLogin();
// 强制检查,未登录时抛出NotLoginException
StpUtil.checkLogin();
// 获取当前登录用户ID
Object loginId = StpUtil.getLoginId();
// 安全获取用户ID,未登录时返回默认值
Object loginId = StpUtil.getLoginId(0);
// 获取用户ID并转换类型
String userId = StpUtil.getLoginIdAsString();
int userIdInt = StpUtil.getLoginIdAsInt();
long userIdLong = StpUtil.getLoginIdAsLong();
Token信息管理
// 获取Token名称
String tokenName = StpUtil.getTokenName();
// 获取当前Token值
String tokenValue = StpUtil.getTokenValue();
// 获取完整Token信息
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
// 手动设置Token值
StpUtil.setTokenValue("custom-token-value");
权限校验API
角色校验
// 获取用户角色列表
List<String> roleList = StpUtil.getRoleList();
// 检查是否拥有某个角色
boolean hasRole = StpUtil.hasRole("admin");
// 检查多个角色(AND关系)
boolean hasAllRoles = StpUtil.hasRoleAnd("admin", "user");
// 检查多个角色(OR关系)
boolean hasAnyRole = StpUtil.hasRoleOr("admin", "guest");
// 强制校验角色
StpUtil.checkRole("admin"); // 无权限时抛出NotRoleException
权限校验
// 获取用户权限列表
List<String> permissionList = StpUtil.getPermissionList();
// 检查是否拥有某个权限
boolean hasPermission = StpUtil.hasPermission("user:add");
// 检查多个权限(AND关系)
boolean hasAllPermissions = StpUtil.hasPermissionAnd("user:add", "user:delete");
// 检查多个权限(OR关系)
boolean hasAnyPermission = StpUtil.hasPermissionOr("user:add", "user:view");
// 强制校验权限
StpUtil.checkPermission("user:add"); // 无权限时抛出NotPermissionException
会话管理API
Account Session管理
// 获取当前用户的Session
SaSession session = StpUtil.getSession();
// 获取指定用户的Session
SaSession userSession = StpUtil.getSessionByLoginId(10001);
// Session数据操作
session.set("userInfo", userObject); // 设置数据
Object data = session.get("userInfo"); // 获取数据
session.delete("userInfo"); // 删除数据
session.clear(); // 清空所有数据
Token Session管理
// 获取当前Token的Session
SaSession tokenSession = StpUtil.getTokenSession();
// 获取指定Token的Session
SaSession specificTokenSession = StpUtil.getTokenSessionByToken("token-value");
// 匿名Token Session(未登录状态下使用)
SaSession anonSession = StpUtil.getAnonTokenSession();
注销与强制下线
正常注销
// 当前用户注销
StpUtil.logout();
// 注销指定用户
StpUtil.logout(10001);
// 注销指定用户的特定设备
StpUtil.logout(10001, "APP");
强制下线
// 强制指定用户下线
StpUtil.forceLogout(10001);
// 强制指定用户的特定设备下线
StpUtil.forceLogout(10001, "PC");
// 通过Token值强制下线
StpUtil.forceLogoutByTokenValue("token-value");
有效期管理
Token有效期控制
// 获取Token剩余有效期
long timeout = StpUtil.getTokenTimeout();
// 获取Session剩余有效期
long sessionTimeout = StpUtil.getSessionTimeout();
// 续期Token
StpUtil.renewTimeout(3600); // 续期1小时
// 续期指定Token
StpUtil.renewTimeout("token-value", 3600);
活跃度检查
// 获取最后活跃时间
long lastActiveTime = StpUtil.getTokenLastActiveTime();
// 获取活跃超时剩余时间
long activeTimeout = StpUtil.getTokenActiveTimeout();
// 更新活跃时间
StpUtil.updateLastActiveToNow();
// 检查活跃状态(超时抛出异常)
StpUtil.checkActiveTimeout();
多端设备管理
设备信息查询
// 获取当前登录设备类型
String deviceType = StpUtil.getLoginDeviceType();
// 获取当前设备ID
String deviceId = StpUtil.getLoginDeviceId();
// 获取用户所有登录设备
List<SaTerminalInfo> terminals = StpUtil.getTerminalListByLoginId(10001);
// 获取用户特定类型设备
List<SaTerminalInfo> appTerminals = StpUtil.getTerminalListByLoginId(10001, "APP");
Token反查
// 根据用户ID获取Token
String token = StpUtil.getTokenValueByLoginId(10001);
// 获取用户所有Token
List<String> tokens = StpUtil.getTokenValueListByLoginId(10001);
// 获取用户特定设备的Token
String appToken = StpUtil.getTokenValueByLoginId(10001, "APP");
高级功能API
二级认证
// 开启二级认证
StpUtil.openSafe(300); // 有效期5分钟
// 检查二级认证状态
boolean isSafe = StpUtil.isSafe();
// 强制校验二级认证
StpUtil.checkSafe();
// 关闭二级认证
StpUtil.closeSafe();
账号限制
// 限制账号
StpUtil.restrict(10001, 3600); // 限制1小时
// 检查限制状态
boolean isRestricted = StpUtil.isRestricted(10001);
// 获取限制剩余时间
long restrictTime = StpUtil.getRestrictTime(10001);
// 解除账号限制
StpUtil.removeRestriction(10001);
身份切换
// 临时切换身份
StpUtil.switchTo(10002);
// 在代码块内临时切换
StpUtil.switchTo(10002, () -> {
// 在此代码块内身份为10002
System.out.println("当前身份: " + StpUtil.getLoginId());
});
// 结束身份切换
StpUtil.endSwitch();
会话查询与搜索
高级查询功能
// 搜索Token
List<String> tokens = StpUtil.searchTokenValue("user", 0, 10, true);
// 搜索Session ID
List<String> sessionIds = StpUtil.searchSessionId("active", 0, 10, false);
// 搜索Token Session ID
List<String> tokenSessionIds = StpUtil.searchTokenSessionId("web", 0, 10, true);
最佳实践建议
-
登录场景选择:根据业务需求选择合适的登录方式,普通Web应用使用基础登录,多端应用使用设备类型区分。
-
权限设计:建议使用RBAC模型,通过角色分配权限,避免直接分配具体权限给用户。
-
会话管理:合理设置Token有效期和活跃超时时间,平衡安全性和用户体验。
-
异常处理:妥善处理NotLoginException、NotRoleException、NotPermissionException等异常。
-
性能优化:对于频繁访问的权限数据,可以考虑缓存策略提升性能。
StpUtil的API设计遵循"约定优于配置"的原则,大多数功能都可以通过一行代码实现,极大简化了权限认证的开发工作。通过合理组合使用这些API,可以构建出安全、灵活、易维护的权限系统。
多端登录与同端互斥登录实现
在现代应用开发中,用户往往需要在多个设备上同时使用同一个账号,比如在PC端、移动端、平板端等不同设备上登录。Sa-Token通过灵活的配置和强大的API,为开发者提供了完善的多端登录和同端互斥登录解决方案。
核心配置参数
Sa-Token通过三个关键配置参数来控制多端登录行为:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
isConcurrent | Boolean | true | 是否允许同一账号多地同时登录 |
isShare | Boolean | false | 多人登录同一账号时是否共用一个Token |
maxLoginCount | int | 12 | 同一账号最大登录数量限制 |
多端登录实现原理
Sa-Token通过deviceType(设备类型)参数来区分不同的登录终端。每个设备类型下的登录会话相互独立,互不干扰。
设备类型管理
// 默认设备类型常量
public static final String DEFAULT_LOGIN_DEVICE_TYPE = "DEF";
// 登录时指定设备类型
StpUtil.login(10001, "PC"); // PC端登录
StpUtil.login(10001, "APP"); // 移动端登录
StpUtil.login(10001, "PAD"); // 平板端登录
StpUtil.login(10001, "WECHAT"); // 微信小程序登录
登录会话数据结构
Sa-Token使用Account-Session来管理用户的所有登录终端信息:
同端互斥登录机制
当isConcurrent配置为false时,Sa-Token会启用同端互斥登录机制。这意味着在同一设备类型下,新的登录会顶替掉旧的登录会话。
互斥登录流程
互斥范围控制
Sa-Token提供了灵活的互斥范围控制:
public enum SaReplacedRange {
CURR_DEVICE_TYPE, // 仅顶替当前设备类型的会话
ALL_DEVICE_TYPE // 顶替所有设备类型的会话
}
配置示例:
sa-token:
is-concurrent: false
replaced-range: CURR_DEVICE_TYPE # 或 ALL_DEVICE_TYPE
会话数量限制
通过maxLoginCount参数,可以限制同一账号的最大登录数量:
// 配置最大登录数量为5
config.setMaxLoginCount(5);
// 登录时也可以临时指定
StpUtil.login(10001, new SaLoginParameter()
.setDeviceType("PC")
.setMaxLoginCount(3));
当登录数量超过限制时,Sa-Token会按照登录时间顺序,自动注销最早的登录会话。
终端信息查询与管理
Sa-Token提供了丰富的API来查询和管理终端信息:
// 获取指定账号的所有终端列表
List<SaTerminalInfo> terminalList = StpUtil.getTerminalListByLoginId(10001);
// 获取指定设备类型的终端列表
List<SaTerminalInfo> pcTerminals = StpUtil.getTerminalListByLoginId(10001, "PC");
// 获取指定账号的Token列表
List<String> tokenList = StpUtil.getTokenValueListByLoginId(10001);
// 强制注销指定设备类型的会话
StpUtil.logout(10001, "PC"); // 正常注销
StpUtil.forceLogout(10001, "PC"); // 强制下线
StpUtil.replaced(10001, "PC"); // 顶替下线
实际应用场景
场景1:多端同时在线
sa-token:
is-concurrent: true # 允许多地同时登录
is-share: false # 每个登录创建独立Token
max-login-count: -1 # 不限制登录数量
用户可以在PC、手机、平板等不同设备上同时登录,每个设备都有独立的会话。
场景2:同端互斥登录
sa-token:
is-concurrent: false # 启用互斥登录
replaced-range: CURR_DEVICE_TYPE # 仅同设备类型互斥
用户可以在PC和手机端同时登录,但不能在两个PC端同时登录。
场景3:全局单点登录
sa-token:
is-concurrent: false
replaced-range: ALL_DEVICE_TYPE # 所有设备类型互斥
用户只能在一个设备上登录,新登录会顶替所有旧会话。
高级特性
设备ID精确控制
除了设备类型,还可以使用设备ID进行更精确的控制:
// 登录时指定设备ID
StpUtil.login(10001, new SaLoginParameter()
.setDeviceType("APP")
.setDeviceId("IMEI123456789"));
// 按设备ID注销
StpUtil.logout(10001, new SaLogoutParameter()
.setDeviceType("APP")
.setDeviceId("IMEI123456789"));
自定义终端扩展数据
可以为每个登录终端添加自定义扩展数据:
StpUtil.login(10001, new SaLoginParameter()
.setDeviceType("PC")
.setTerminalExtra("ip", "192.168.1.100")
.setTerminalExtra("browser", "Chrome")
.setTerminalExtra("os", "Windows 10"));
最佳实践建议
- 设备类型命名规范:建议使用大写英文单词作为设备类型标识,如"PC"、"APP"、"PAD"等
- 合理设置最大登录数:根据业务需求设置合适的
maxLoginCount,避免资源浪费 - 设备ID管理:对于移动端应用,建议使用设备唯一标识作为deviceId
- 会话监控:定期检查终端列表,及时清理异常或过期的会话
- 安全考虑:对于敏感操作,建议启用二次认证或设备绑定机制
通过Sa-Token的多端登录与同端互斥登录功能,开发者可以轻松构建安全、灵活的用户会话管理体系,满足各种复杂的业务场景需求。
会话管理与Token风格定制
在现代Web应用开发中,会话管理和Token生成策略是身份认证系统的核心组成部分。Sa-Token框架提供了强大而灵活的会话管理机制,以及多样化的Token风格定制选项,让开发者能够根据业务需求打造最适合的认证方案。
会话管理体系架构
Sa-Token的会话管理采用了三层架构设计,分别对应不同的业务场景:
1. Account-Session(账号会话)
每个登录账号拥有独立的会话空间,用于存储账号级别的数据,如用户
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



