Sa-Token 名词解释Token、Session、loginId 与登录鉴权策略的系统梳理【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token在 Sa-Token 中TokenSession登录策略这些词经常被混用而绝大多数会话逻辑 bug 的根源正是对这些基础概念的理解偏差。本文以官方文档《Sa-Token 名词解释》(sa-token-doc-new/docs/more/noun-intro.md) 为核心骨架结合 StpUtil.java、SaTokenConfig.java 等源码逐一澄清五种 Token、两种过期时间、三种 Session、账号标识、登录/注销策略与三种鉴权方式帮助你在阅读文档、排查问题和提出 issue 之前先建立准确的术语体系。一、几种 Token按产生来源区分五种令牌Sa-Token 官方文档首先强调Token 并非只有一种按产生来源可分为五类混用名称是最常见的理解偏差来源。名称产生入口常见别名作用token会话 TokenStpUtil.login()satoken、会话Token维护用户登录状态temp-token临时 TokenSaTempUtil.createToken()临时Token一次性接口防盗用、短时间资源访问Access-TokenOAuth2 模块访问令牌、资源令牌OAuth2 客户端访问授权资源的身份凭证Refresh-TokenOAuth2 模块刷新令牌用于换取新的 Access-TokenSame-TokenSaSameUtil模块同源令牌子服务外网隔离场景下的内部调用鉴权会话 Tokensatoken即配置项tokenName默认值satoken所对应的令牌。从 StpUtil.java 可以看到StpUtil.login(Object id)、StpUtil.login(Object id, String deviceType)、StpUtil.login(Object id, SaLoginParameter loginParameter)等重载统一委托给成员变量stpLogicStpLogic对象完成登录并生成会话 TokenSaTokenConfig.java 中tokenName的注释也印证了它同时是Cookie 名称、提交 token 时参数的名称、存储 token 时的 key 前缀。临时 TokenSaTempUtil.java 是独立的临时 token 验证模块其类注释写明用途有效期很短的一种 token一般用于一次性接口防盗用、短时间资源访问等业务场景。核心 API 为// 为指定 value 创建一个临时 tokentimeout 单位秒-1 代表永久有效 String token SaTempUtil.createToken(value, timeout); // 解析 Token 获取 value Object value SaTempUtil.parseToken(token);它与会话 Token 的关键区别在于不产生登录态、不与loginId绑定仅做值 ↔ 令牌的短期映射。Access-Token 与 Refresh-Token这两个令牌由 OAuth2 模块产生其常量定义见 SaOAuth2Consts.java配套的access_token/refresh_token校验逻辑分布在sa-token-plugin/sa-token-oauth2目录下如 SaOAuth2DataResolver.java。注意它与会话 Token的区别OAuth2 的 Access-Token 授权主体是客户端应用而会话 Token 授权主体是登录用户。Same-TokenSaSameUtil.java 是Samed-Token 同源系统身份认证模块类注释说明其目标是解决同源系统互相调用时的身份认证校验例如微服务网关请求转发鉴权、微服务 RPC 调用鉴权。常用 API// 获取 Same-Token不存在则立即创建 String sameToken SaSameUtil.getToken(); // 校验一个 Same-Token 是否有效无效抛异常 SaSameUtil.checkToken(token);其有效期由全局配置项sameTokenTimeout控制默认 1 天见 SaTokenConfig.java。二、两种过期时间timeout 与 active-timeout文档把会话 Token 的过期机制归纳为两个独立参数timeout会话 Token 的长久有效期即 Token 最长能用多久active-timeout会话 Token 的最低活跃频率即 Token 必须隔多久至少访问一次系统否则被冻结。两者的官方配置形式源自 token-timeout.mdsa-token: # token 有效期单位秒默认30天-1代表永不过期 timeout: 2592000 # token 最低活跃频率单位秒如果 token 超过此时间没有访问系统就会被冻结默认-1 代表不限制永不冻结 active-timeout: -1# properties 风格 sa-token.timeout2592000 sa-token.active-timeout-1源码侧这两个参数的定义与默认值见 SaTokenConfig.java/** token 有效期单位秒 默认30天-1 代表永久有效 */ private long timeout 60 * 60 * 24 * 30; /** * token 最低活跃频率单位秒如果 token 超过此时间没有访问系统就会被冻结 * 默认-1 代表不限制永不冻结例如可以设置为 1800 代表 30 分钟内无操作就冻结 */ private long activeTimeout -1;官方文档用银行储蓄卡来类比timeout相当于卡的最长使用年限到期卡被删除Token 过期必须重新登录active-timeout相当于最低活跃要求长期不动则被冻结Token 被冻结但不会被删除。两者可单独配置也可同时配置只要有一个过期 Token 就不可用。与这两种过期时间直接相关的 API 都能在 StpUtil.java 中找到StpUtil.checkActiveTimeout()检查当前 Token 是否已被冻结冻结则抛异常StpUtil.updateLastActiveToNow()手动续签将最后操作时间更新为当前时间戳StpUtil.getTokenActiveTimeout()/StpUtil.getTokenTimeout()分别查询距离冻结还剩多久、Token 剩余有效时间返回 -1 代表永久有效-2 代表没有该值StpUtil.renewTimeout(long timeout)重置 token 的 timeout 有效期。此外配置项autoRenew默认true控制框架是否在每次直接或间接调用getLoginId()时自动进行过期检查与续签可设为false将续签完全交给开发者手动控制。三、三种 Session账号维度、令牌维度、自定义维度Sa-Token 文档将 Session 分为三种区别在于按什么主键分配Session 类型分配主键获取方式Account-Session账号 Session账号 idStpUtil.getSession()Token-Session令牌 Session每个 TokenStpUtil.getTokenSession()Custom-Session自定义 Session任意指定的 SessionIdSaSessionCustomUtil.getSessionById(id)Account-Session框架只在调用StpUtil.login(id)登录时才产生 Session且 Session 分配给账号 id而非客户端——PC 端和 APP 端登录同一账号得到的是同一个 Session天然支持多端数据同步。操作示例// 获取当前会话的 Account-Session SaSession session StpUtil.getSession(); // 从 Account-Session 中读取、写入数据 session.get(name); session.set(name, 张三);对应源码入口为 StpUtil.java 的getSession()、getSessionByLoginId(Object loginId)等 Account-Session 相关方法区。Token-Session当需要每个客户端独立的数据典型场景某端两小时无操作自动下线时把数据放进共享的 Account-Session 会导致多端互相续命。Token-Session 就是按每个 Token 独立分配的// 获取当前会话的 Token-Session SaSession session StpUtil.getTokenSession(); session.set(name, 张三);不同设备即使登录同一账号只要 token 不同对应的 Token-Session 就不同。相关 API 见 StpUtil.java包括getTokenSessionByToken(String tokenValue)与未登录也可使用的getAnonTokenSession()。另外配置项rightNowCreateTokenSession默认false决定 Token-Session 是登录时立即创建还是首次调用getTokenSession()时惰性创建见 SaTokenConfig.java。Custom-Session不依赖账号 id 或 token以任意指定值作为 SessionId可理解为通用的分布式缓存 Session// 获取指定 key 的 Custom-Session SaSession session SaSessionCustomUtil.getSessionById(goods-10001); session.set(name, 张三);对应实现位于 SaSessionCustomUtil.java。Custom-Session 的会话有效期默认取全局配置的timeout创建后可用session.updateTimeout(1000)单独修改。三者的完整模型与结构图解见官方 Session模型详解三个客户端登录同一账号不共享 token时指向同一个 Account-Session但各自持有不同的 Token-Session简而言之——Account-Session 以账号 id 为主Token-Session 以 token 为主Custom-Session 以特定 key 为主。四、账号标识loginId、device、loginType文档把标识一个登录会话拆成三个正交维度loginId账号 id用来区分不同账号通过StpUtil.login(id)指定。从 StpUtil.java 的注释看建议类型为long | int | Stringdevice登录设备类型例如PC、APP通过StpUtil.login(id, deviceType)指定loginType账号类型账号体系标识用来区分同一系统中的User账号和Admin账号。loginType 的机制在源码中非常直白StpUtil是一个空壳门面类所有静态方法都转发给成员变量stpLogic而其TYPE常量固定为loginpublic class StpUtil { /** 多账号体系下的类型标识 */ public static final String TYPE login; /** 底层使用的 StpLogic 对象 */ public static StpLogic stpLogic new StpLogic(TYPE); // 所有静态方法均为对 stpLogic 的转发 }由此推出多账号体系的做法新建一个StpUserUtil把TYPE改为user即可得到一套与StpUtil完全隔离的登录/鉴权体系也可以不复制类直接声明new StpLogic(user)Kit 模式。完整方案含注解鉴权的type属性、注解合并、同端多登录的 tokenName 隔离等见 多账号认证文档。注意 device 在 API 中实际以deviceType命名SaLoginParameter.java 中字段名为deviceType并额外提供deviceId设备 id供设备锁等场景使用旧的setDevice()/getDevice()已标记Deprecated应改用setDeviceType()。五、几种登录策略从文档概念到配置项文档列出的七种登录策略在 Sa-Token 中分别对应明确的配置项或独立模块。以下对照表以 SaTokenConfig.java 中的字段注释为依据文档中的策略含义对应实现/配置单地登录单端登录同一时间只能在一处登录新登录挤掉旧登录isConcurrent: false多地登录多端登录不同地方可同时登录新旧共存isConcurrent: true默认同端互斥登录同类型设备单地点、不同类型设备可共存参考 QQ 的登录模式isConcurrent: true 登录时指定device顶替范围由replacedRange控制限量登录限制账号登录设备总数超量后自动清退一个旧登录maxLoginCount默认 12overflowLogoutMode记住我模式设备重启后仍保持登录状态isLastingCookie: true持久 Cookie单点登录进入多个系统只需登录一次SSO 模块独立插件/文档体系同端多登录一个终端同时登录多个账号多账号体系 重写 tokenName 防覆盖逐项说明单地/多地登录isConcurrent字段注释为是否允许同一账号多地同时登录为 true 时允许一起登录, 为 false 时新登录挤掉旧登录默认true。isConcurrentfalse时还可以用replacedLoginExitModeOLD_DEVICE旧设备下线 /NEW_DEVICE新设备登录失败决定新旧设备谁放弃会话用replacedRangeCURR_DEVICE_TYPE/ALL_DEVICE_TYPE决定顶替范围。互斥登录的典型实践见 互斥登录文档。限量登录maxLoginCount同一账号最大登录数量-1 不限只在isConcurrenttrue, isSharefalse时生效溢出时以何种方式清退旧会话由overflowLogoutMode决定LOGOUT注销下线、KICKOUT踢人下线、REPLACED顶人下线。记住我isLastingCookie默认true决定 Cookie 是持久的还是临时的。StpUtil.login(id, isLastingCookie)还支持按单次登录动态指定。实现细节见 记住我模式文档。单点登录由独立 SSO 方案实现概念与部署见 SSO 文档。同端多登录即一个终端同时登录多个账号。默认两套账号体系的 token 都写在名为satoken的载体里会互相覆盖解决方式是重写stpLogic.splicingKeyTokenName()让不同体系使用不同 token 名称详见 多账号认证文档 第 8 节。登录参数的两种方式全局配置 与 按次覆盖以上所有登录行为都可以按次登录覆盖这正是loginId/device之外的第三个重要类——SaLoginParameter.java。它的无参构造器会以全局SaTokenConfig为默认值初始化未指定的项自动继承全局配置// 全局配置yml // sa-token: // is-concurrent: true // max-login-count: 12 // is-lasting-cookie: true // 按次覆盖此次登录仅 PC 端、有效期七天、不共享 token StpUtil.login(10001, new SaLoginParameter() .setDeviceType(PC) .setTimeout(60 * 60 * 24 * 7) .setIsShare(false));SaLoginParameter可覆盖的字段包括deviceType、deviceId、timeout、activeTimeout、isConcurrent、isShare、maxLoginCount、isLastingCookie、replacedRange、overflowLogoutMode、rightNowCreateTokenSession以及 Cookie 配置等且每个字段均提供 setter 链式调用便于登录接口中按业务动态组装登录行为。六、几种注销策略文档列出四种注销策略其核心差异在注销影响半径注销策略含义单端注销只在调用登录的一端注销全端注销一端注销全端下线同端注销发起注销后同类型设备端一起下线不同设备类型不受影响单点注销一个系统注销所有系统一起下线SSO 场景源码层面的基础抽象是枚举 SaLogoutRange.javapublic enum SaLogoutRange { /** token 范围只注销提供的 token 指向的会话 */ TOKEN, /** 账号范围注销 token 指向的 loginId 会话 */ ACCOUNT }全局默认值由配置项logoutRange指定默认TOKEN即单端注销见 SaTokenConfig.java。同端注销则通过在注销时传入deviceType参数实现——StpUtil.java 提供了按loginId deviceType维度操作的logout(Object loginId, String deviceType)、kickout(Object loginId, String deviceType)、replaced(Object loginId, String deviceType)等重载注释中均说明填 null 代表覆盖该账号的所有设备类型。另外要注意注销、踢人、顶人三种下线方式的语义差异均定义在 StpUtil.javalogout主动注销对端再次访问提示未登录kickout踢人下线对端再次访问抛NotLoginException场景值-5replaced顶人下线对端再次访问抛NotLoginException场景值-4用于新登录挤掉旧登录场景。单点注销属于 SSO 体系的注销扩展见 SSO 注销文档。七、几种鉴权方式代码、注解、路由拦截文档把鉴权落地方式归纳为三种源码中三者齐备1、代码鉴权在代码里直接调用StpUtil.checkXxx相关 API最灵活、可任意嵌套条件// 校验当前会话是否已登录未登录抛 NotLoginException StpUtil.checkLogin(); // 校验当前账号是否拥有指定角色/权限 StpUtil.checkRole(admin); StpUtil.checkPermission(article:add); // 需要自定义逻辑时也可先 isXxx 判断再自行抛错 if(StpUtil.hasRole(vip)) { ... }这些方法集中在 StpUtil.java 的角色认证操作与权限认证操作两个分区中。2、注解鉴权在方法或类上添加SaCheckXxx注解。注解定义位于sa-token-core的annotation包下如 SaCheckLogin.java、SaCheckRole、SaCheckPermission、SaCheckSafe等每个注解配有独立的 handlerannotation/handler目录下的SaCheckLoginHandler等。多账号体系下可通过注解的type属性指定校验哪套账号// 校验的是自定义 StpUserUtil 体系typeuser的登录态 SaCheckLogin(type StpUserUtil.TYPE) RequestMapping(info) public String info() { return 查询用户信息; }3、路由拦截鉴权在全局过滤器或拦截器里通过SaRouter.match()拦截路由做集中鉴权是按 URL 白名单/黑名单管控的常用形态// 在拦截器中匹配一批路由未登录一律拦截 SaRouter.match(/admin/**).check(r - StpUtil.checkRole(admin)); // 混合多账号体系示例来自多账号认证文档 SaRouter.match(/art/getInfo).check(r - StpUtil.checkLogin()); SaRouter.match(/art/getInfo).check(r - StpUserUtil.checkLogin());路由匹配器实现见 SaRouter.java它与SaFilterServlet 过滤器及 Spring/Reactor/Solon 等平台的拦截器 starter 配合使用。八、小结一张表建立 Sa-Token 术语坐标系概念族成员一句话区分Tokentoken / temp-token / Access-Token / Refresh-Token / Same-Token按产生模块区分登录模块、临时验证模块、OAuth2 模块、同源认证模块过期时间timeout / active-timeout前者管最长活多久后者管多久不活跃就冻结SessionAccount-Session / Token-Session / Custom-Session按账号 id / 按 token / 按自定义 key 分配账号标识loginId / device / loginType哪个账号 / 哪种设备 / 哪套账号体系登录策略单地、多地、同端互斥、限量、记住我、单点、同端多登录由 isConcurrent、replacedRange、maxLoginCount、isLastingCookie、SSO 模块、tokenName 隔离组合实现注销策略单端 / 全端 / 同端 / 单点注销由 logoutRange 与 deviceType 维度控制SSO 注销覆盖多系统鉴权方式代码 / 注解 / 路由拦截checkXxxAPI、SaCheckXxx、SaRouter.match()以上每个条目均可在当前仓库中定位到实现登录与鉴权 API 见 StpUtil.java核心逻辑在StpLogic全局配置见 SaTokenConfig.java按次登录参数见 SaLoginParameter.java。遇到Token 过期Session 不同步新旧设备互踢类问题时建议先回到本表的坐标系确认自己讨论的到底是哪一种 Token、哪一层 Session、哪个维度的注销策略再对照 登录认证文档 与 Token有效期详解 定位配置项可避免绝大多数因概念混淆导致的误判。【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考