码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【RuoYi-Vue-Plus】学习笔记 31 - Sa-Token(五)登录验证拦截器之 Token 有效期及其续签(Sa-Token 源码)


    文章目录

      • 前言
      • 参考目录
      • 框架集成
        • 基于 Sa-Token 最新版本
        • yaml 配置文件
        • Sa-Token 配置 `SaTokenConfig` 注册拦截器
      • 功能调用流程分析
        • 1、获取当前会话账号id `StpLogic#getLoginId()`
        • 1.1、检查 token 是否已经临时过期 `StpLogic#checkActivityTimeout`
        • 1.1.1、计算过期时间 `StpLogic#getTokenActivityTimeoutByToken`
        • 1.2、已过期抛出异常 `NotLoginException` (Token已过期)
        • 1.3、未过期,完成验证
        • 2、续签 `StpLogic#updateLastActivityToNow`
        • 3、完成所有步骤,返回 loginId
      • 扩展分析
        • 扩展1、关于手动续签
        • 扩展2、为什么需要两个 timeout ?
        • 扩展3、关于 [存储器] 包装类 `SaStorage`
        • 扩展4、登录接口中 `SaStorage` 使用
        • 扩展5、设置注解允许匿名访问的url `ExcludeUrlProperties`

    前言

    前几天在群里面聊到关于 token 续签的问题,这个在 Sa-Token 官方文档也有相应的说明,这篇文章还是从源码角度去看看到底做了什么。

    参考目录

    • Sa-Token 官方文档:Token有效期详解

    框架集成

    基于 Sa-Token 最新版本

    在这里插入图片描述

    yaml 配置文件

    这里需要关注的是两个 timeout 配置:
    在这里插入图片描述

    Sa-Token 配置 SaTokenConfig 注册拦截器

    SaTokenConfig#addInterceptors
    在这里插入图片描述
    这里重点关注 StpUtil.checkLogin() 这个方法,其他的会放在后面扩展去简单进行讨论。

    功能调用流程分析

    关于 StpUtil.checkLogin() 底层的调用过程比较简单容易理解,所以没有画流程图。

    从上面 SaTokenConfig#addInterceptors 开始进入,到 StpUtil#checkLogin :
    在这里插入图片描述
    再深入一层,到 StpLogic#checkLogin:
    在这里插入图片描述
    然后到今天的主角 StpLogic#getLoginId()。

    1、获取当前会话账号id StpLogic#getLoginId()

    在这里插入图片描述
    注释都写得很明白了,先是进行各种判断,如果全部通过了,来到最后两个方法:

    1. 检查是否临时过期
      这里的checkActivityTimeout 检查的值对应的是配置文件中的 activity-timeout 属性值。
    2. 判断是否自动续签
      续签的时间也是对应的是配置文件中的 activity-timeout 属性值。

    1.1、检查 token 是否已经临时过期 StpLogic#checkActivityTimeout

    在这里插入图片描述

    1.1.1、计算过期时间 StpLogic#getTokenActivityTimeoutByToken

    在这里插入图片描述

    1.2、已过期抛出异常 NotLoginException (Token已过期)

    在这里插入图片描述
    全局异常处理 GlobalExceptionHandler#handleNotLoginException:
    在这里插入图片描述
    控制台输出:
    在这里插入图片描述

    1.3、未过期,完成验证

    未过期则打上检查标记,完成验证。
    在这里插入图片描述

    2、续签 StpLogic#updateLastActivityToNow

    在这里插入图片描述
    续签实际上就是更新缓存中的最后操作时间为当前时间。
    在这里插入图片描述

    3、完成所有步骤,返回 loginId

    在这里插入图片描述
    至此,拦截器登录检查完成。

    扩展分析

    扩展1、关于手动续签

    图源 Sa-Token 官方文档:
    这里是引用

    官方提供了手动续签的方法,底层也是调用了上面续签的方法 StpLogic#updateLastActivityToNow 。

    值得注意的是,手动续签的时候如果判断 token 临时有效期过期了,依然可以续签成功,因为续签方法是单独的,并没有判断 token 的状态。换句话说,如果捕获到 NotLoginException 异常,那么可以在 catch 中进行手动续签。
    在这里插入图片描述
    这样的话依然可以返回正确结果,而非抛出 401 异常。

    扩展2、为什么需要两个 timeout ?

    关于这个问题,我询问了一下 狮子大佬 ,他说得比较详细,我直接贴出来:

    这里是引用
    在这里插入图片描述

    扩展3、关于 [存储器] 包装类 SaStorage

    在前面 1.1、检查 token 是否已经临时过期 里面的方法有用到这个对象(存取检查标记),所以拿出来说一下。

    通过查找源码可以得知这个对象是一开始被 Spring 加载到容器中的,本质上就是一个 Servletcontext 对象。

    先从 1.1 方法 StpLogic#checkActivityTimeout 回溯:
    调用方法 SaStorage storage = SaHolder.getStorage();
    在这里插入图片描述
    SaManager#getSaTokenContextOrSecond
    在这里插入图片描述
    Sa-Token 上下文处理器 SaTokenContext
    在这里插入图片描述
    关于 SaTokenContext 官方文档 也有作介绍:

    在这里插入图片描述

    最后一段话很重要,继续找源头:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    至此可知 SaStorage 的完整创建流程。

    扩展4、登录接口中 SaStorage 使用

    在之前登录接口中也有用到这个对象,因此可以在这里也整理一下。
    StpLogic#login
    在这里插入图片描述
    StpLogic#setTokenValueToStorage
    在这里插入图片描述

    扩展5、设置注解允许匿名访问的url ExcludeUrlProperties

    在配置拦截器时需要排除指定的路径,如下:
    在这里插入图片描述
    参考 框架wiki ,主要有两个途径:

    1. yaml 配置文件
      在这里插入图片描述
    2. 配置 @Anonymous 注解
      在这里插入图片描述

    第一种比较简单,直接读取配置文件,我们聊聊第二种。

    ExcludeUrlProperties
    在这里插入图片描述
    这个类是懒加载方式,第一次请求的时候才会将所有需要过滤的请求放到数组 excludes 中(RequestMappingHandlerMapping 能获取到容器中所有请求的方法),并且只会加载一次。

    这里会对 /demo/demo/{id} 这种路径进行替换变成 /demo/demo/*。
    在这里插入图片描述
    在这里插入图片描述
    但是要注意路径要唯一,否则会把同级别其他路径一起进行过滤:

    在这里插入图片描述

  • 相关阅读:
    三个本地组策略的设置实例
    zookeeper源码(09)follower处理客户端请求
    软件开发人员 Kubernetes 入门指南|Part 2
    Appium自动化测试基础 — ADB常用命令(二)
    消息队列-kafka-服务端处理架构(架构,Topic文件结构,服务端数据的一致性)
    如何成为一个全栈数字化设计师
    [数据可视化] 饼图(Pie Chart)
    flutter系列之:构建Widget的上下文环境BuildContext详解
    【无标题】
    跑步需要哪些运动装备?跑步爱好者者的装备推荐
  • 原文地址:https://blog.csdn.net/Michelle_Zhong/article/details/126071871
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号