Sa-Token登录认证模块深度探索

Sa-Token登录认证模块深度探索

【免费下载链接】Sa-Token 一个轻量级 Java 权限认证框架,让鉴权变得简单、优雅!—— 登录认证、权限认证、分布式Session会话、微服务网关鉴权、单点登录、OAuth2.0 【免费下载链接】Sa-Token 项目地址: https://gitcode.com/GitHub_Trending/sa/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);

最佳实践建议

  1. 登录场景选择:根据业务需求选择合适的登录方式,普通Web应用使用基础登录,多端应用使用设备类型区分。

  2. 权限设计:建议使用RBAC模型,通过角色分配权限,避免直接分配具体权限给用户。

  3. 会话管理:合理设置Token有效期和活跃超时时间,平衡安全性和用户体验。

  4. 异常处理:妥善处理NotLoginException、NotRoleException、NotPermissionException等异常。

  5. 性能优化:对于频繁访问的权限数据,可以考虑缓存策略提升性能。

StpUtil的API设计遵循"约定优于配置"的原则,大多数功能都可以通过一行代码实现,极大简化了权限认证的开发工作。通过合理组合使用这些API,可以构建出安全、灵活、易维护的权限系统。

多端登录与同端互斥登录实现

在现代应用开发中,用户往往需要在多个设备上同时使用同一个账号,比如在PC端、移动端、平板端等不同设备上登录。Sa-Token通过灵活的配置和强大的API,为开发者提供了完善的多端登录和同端互斥登录解决方案。

核心配置参数

Sa-Token通过三个关键配置参数来控制多端登录行为:

配置项类型默认值说明
isConcurrentBooleantrue是否允许同一账号多地同时登录
isShareBooleanfalse多人登录同一账号时是否共用一个Token
maxLoginCountint12同一账号最大登录数量限制

多端登录实现原理

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来管理用户的所有登录终端信息:

mermaid

同端互斥登录机制

isConcurrent配置为false时,Sa-Token会启用同端互斥登录机制。这意味着在同一设备类型下,新的登录会顶替掉旧的登录会话。

互斥登录流程

mermaid

互斥范围控制

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"));

最佳实践建议

  1. 设备类型命名规范:建议使用大写英文单词作为设备类型标识,如"PC"、"APP"、"PAD"等
  2. 合理设置最大登录数:根据业务需求设置合适的maxLoginCount,避免资源浪费
  3. 设备ID管理:对于移动端应用,建议使用设备唯一标识作为deviceId
  4. 会话监控:定期检查终端列表,及时清理异常或过期的会话
  5. 安全考虑:对于敏感操作,建议启用二次认证或设备绑定机制

通过Sa-Token的多端登录与同端互斥登录功能,开发者可以轻松构建安全、灵活的用户会话管理体系,满足各种复杂的业务场景需求。

会话管理与Token风格定制

在现代Web应用开发中,会话管理和Token生成策略是身份认证系统的核心组成部分。Sa-Token框架提供了强大而灵活的会话管理机制,以及多样化的Token风格定制选项,让开发者能够根据业务需求打造最适合的认证方案。

会话管理体系架构

Sa-Token的会话管理采用了三层架构设计,分别对应不同的业务场景:

1. Account-Session(账号会话)

每个登录账号拥有独立的会话空间,用于存储账号级别的数据,如用户

【免费下载链接】Sa-Token 一个轻量级 Java 权限认证框架,让鉴权变得简单、优雅!—— 登录认证、权限认证、分布式Session会话、微服务网关鉴权、单点登录、OAuth2.0 【免费下载链接】Sa-Token 项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值