sa-token过期机制梳理

sa-token过期机制梳理

1 基本配置

sa-token 配置类

@AutoConfiguration
public class SaTokenConfiguration {
    /**
     * 生成Token实现
     */
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForSimple();
    }

    /**
     * 权限接口实现(使用bean注入方便用户替换)
     */
    @Bean
    public StpInterface stpInterface() {
        return new PlusSaStpInterface();
    }

    /**
     * 自定义token dao层存储
     * 这里使用 redis 实现
     */
    @Bean
    public SaTokenDao saTokenDao() {
        return new PlusSaTokenDao();
    }
}


application.yaml

sa-token:
  # token有效期 设为一天 (必定过期) 单位: 秒
  timeout: 86400
  # 多端不同 token 有效期 可查看 LoginHelper.loginByDevice 方法自定义
  # token最低活跃时间 (指定时间无操作就过期) 单位: 秒
  active-timeout: 1800

2 登录过程

核心源码

// StpLogic.login(Object id, SaLoginModel loginModel)
//   createLoginSession(Object id, SaLoginModel loginModel)
//     saveTokenToIdMapping(tokenValue, id, loginModel.getTimeout());

// 1) 设置 token 信息
getSaTokenDao().set(splicingKeyTokenValue(tokenValue), String.valueOf(loginId), timeout);

// 2) 设置 超时时间
if(isOpenCheckActiveTimeout()) {
    setLastActiveToNow(tokenValue, loginModel.getActiveTimeout(), loginModel.getTimeoutOrGlobalConfig());
}

生成 login 信息,这里使用 redis 实现,redis 的 key 设置了超时时间

# xxxx 为 token
key=Authorization:login:token:xxxxx 
# value 为 用户id信息
value=sys_user:{userId}

同时设置了一个 last-active 时间

# xxxx 为 token
key=Authorization:login:last-active:xxxxx 
# value 为 上一次检查时间的 毫秒时间戳,比如1690878257097
value={last-time}

3 检查过程

核心源码

// 拦截器中添加 StpLogic.checkLogin()
// StpLogic.checkLogin()
//     StpLogic.getLoginId()

// 3、查找此 token 对应的 loginId,如果找不到则抛出:token 无效
// 这里会从 redis 中获取,由于登录时即设置了超时时间,所以token到达了超时时间必然会失效!!!
String loginId = getLoginIdNotHandle(tokenValue);
// getLoginIdNotHandle(tokenValue) 实现 -> getSaTokenDao().get(splicingKeyTokenValue(tokenValue));
if(SaFoxUtil.isEmpty(loginId)) {
    throw NotLoginException.newInstance(loginType, INVALID_TOKEN, INVALID_TOKEN_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11012);
}


// ......

// 7、检查此 token 的最后活跃时间是否已经超过了 active-timeout 的限制,如果是则代表其已被冻结,需要抛出:token 已被冻结
if(isOpenCheckActiveTimeout()) {
    checkActiveTimeout(tokenValue);
    // ------ 至此,loginId 已经是一个合法的值,代表当前会话是一个正常的登录状态了
    // 8、如果配置了自动续签功能, 则: 更新这个 token 的最后活跃时间 (注意此处的续签是在续 active-timeout,而非 timeout)
    if(getConfigOrGlobal().getAutoRenew()) {
        updateLastActiveToNow(tokenValue);
    }
}

也即是会先从 redis 中获取 Authorization:login:token:xxxxx 对应的值,由于该 key 的 timeout 在登录时已经确定了,所以超时后必定获取不到 value 从而报错

获取到了 value 值,那么会接着取出 Authorization:login:last-active:xxxxx 上次登录时的时间戳,与 配置中的 active-timeout 进行比较

  • 如果超过了 active-timeout,直接抛出错误
  • 如果未超过,则刷新 Authorization:login:last-active:xxxxx 的值
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sa-token可以通过以下配置来校验token: 1. 配置token名称:在yml配置文件中,可以通过设置`sa-token.token-name`来指定token的名称,例如`sa-token.token-name: X-Token`\[1\]。 2. 配置token有效期:可以通过设置`sa-token.timeout`来指定token的有效期,单位为秒,默认为30天,可以设置为-1代表永不过期,例如`sa-token.timeout: 2592000`\[1\]。 3. 配置token临时有效期:可以通过设置`sa-token.activity-timeout`来指定token的临时有效期,即在指定时间内无操作就视为token过期,单位为秒,默认为-1,表示不设置临时有效期,例如`sa-token.activity-timeout: -1`\[1\]。 4. 配置是否允许同一账号并发登录:可以通过设置`sa-token.is-concurrent`来指定是否允许同一账号并发登录,为true时允许一起登录,为false时新登录会挤掉旧登录,例如`sa-token.is-concurrent: true`\[1\]。 5. 配置是否共用一个token:可以通过设置`sa-token.is-share`来指定在多人登录同一账号时,是否共用一个token,为true时所有登录共用一个token,为false时每次登录会新建一个token,例如`sa-token.is-share: true`\[1\]。 6. 配置是否输出操作日志:可以通过设置`sa-token.is-log`来指定是否输出操作日志,为true时输出操作日志,为false时不输出操作日志,例如`sa-token.is-log: false`\[1\]。 7. 配置是否使用cookie保存token:可以通过设置`sa-token.is-read-cookie`来指定是否使用cookie保存token,为true时使用cookie保存token,为false时不使用cookie保存token,例如`sa-token.is-read-cookie: false`\[1\]。 8. 配置是否使用head保存token:可以通过设置`sa-token.is-read-head`来指定是否使用head保存token,为true时使用head保存token,为false时不使用head保存token,例如`sa-token.is-read-head: true`\[1\]。 通过以上配置,sa-token可以根据配置的规则来校验token的有效性。 #### 引用[.reference_title] - *1* [最简单的权限验证实现——使用Sa-Token进行权限验证](https://blog.csdn.net/lp840312696/article/details/127072424)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [探索 Sa-Token (一) SpringBoot 集成 Sa-Token](https://blog.csdn.net/weixin_38982591/article/details/126764928)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值