springboot+satoken实现刷新token(值变化)

🎏:你只管努力,剩下的交给时间
🏠 :小破站
springboot+satoken实现刷新token
- satoken是什么?支持什么?
- 为什么需要?
- token一直不变存在的问题
- 1. 安全风险增加
- 2. 难以撤销 Token
- 3. 权限滥用和过期信息的风险
- 4. 缺乏会话管理
- 5. 影响用户隐私
- 6. 无法确保设备和网络变化
- 7. 用户体验不佳
- 逻辑+代码实现
- 代码实现
- 拦截器知识补充
- 1. 注册顺序决定执行顺序
- 2. 拦截器方法的执行顺序
- 3. 优先级控制
- 总结
satoken是什么?支持什么?
satoken官网
借用官网的一句话, Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。
这里我们只说明刷新token,也就是前后端分离的场景中常见的一种方案。
为什么需要?
在satoken中存在两个token,一个是真正的token有效期,还有一个是活跃token,也就是说当活跃token过期的时候是不能访问服务的,需要调用相关方法解除。而当正真的token过期的时候就需要登录重新获取凭证。
所以其实根据上面的表述也是可以实现刷新token的
前端后端约定,当后端因为活跃token过期返回给前端响应的状态值,前端拦截并重新调用相关方法,这样也是可以实现刷新token的。
token一直不变存在的问题
Token 长期不变或过期时间过长会带来一系列安全和用户体验方面的问题。以下是一些主要的风险和潜在问题:
1. 安全风险增加
- Token 被截获的风险:如果攻击者通过某种方式截获了用户的 Token,那么在 Token 长期不变或过期时间过长的情况下,攻击者可以持续使用该 Token 访问用户的账号,而用户不会意识到。这极大增加了账号被恶意使用的风险。
- 无法控制 Token 失效:在 Token 长期有效的情况下,即使用户想要主动注销或更改密码,攻击者手中的旧 Token 仍然有效,导致安全威胁无法解除。
- 无法防御会话劫持:当用户登录后 Token 长期不变,一旦发生会话劫持,攻击者可以一直利用该 Token 冒充用户进行操作,直到 Token 失效。
2. 难以撤销 Token
- Token 黑名单机制的缺乏:当 Token 的有效期非常长时,后端很难立即撤销某个 Token。即使用户账号被禁用或者注销,旧的 Token 可能依然可以继续访问系统,直到 Token 到期。
- 缺乏灵活性:Token 如果是长期有效的,即便用户被强制下线,无法简单地让旧 Token 失效,除非重新设计 Token 管理系统。
3. 权限滥用和过期信息的风险
- 权限变化后无法及时更新:当 Token 长时间有效,而用户的权限发生了变化(例如角色升级、降级或权限被撤销),旧 Token 可能依然具有不该有的权限。这可能导致用户获得不适当的访问权限。
- 过期数据风险:如果用户 Token 长期不更新,系统可能无法捕捉到最新的用户状态变更,比如权限、角色、信息等,导致系统提供了不正确的访问权限或内容。
4. 缺乏会话管理
- 无法追踪用户的活跃度:长期有效的 Token 会让系统无法准确跟踪用户的登录会话。系统无法判断用户是否活跃,用户的最后访问时间也无法准确追踪。
- 无法强制用户重新登录:如果 Token 过期时间过长,用户可能在极长时间内不需要重新登录,丧失了会话管理的能力。对于需要更高安全性的场景,强制用户定期登录是必要的。
5. 影响用户隐私
- 隐私泄露风险增加:Token 长期有效可能使得用户的个人信息在长时间内暴露于潜在的攻击面,增加了隐私泄露的风险。如果用户长期未使用系统,Token 应该过期以保护用户隐私。
- 设备共享中的风险:如果用户在共享设备上登录,而 Token 长期不失效,其他人可以轻松访问用户账户,特别是在用户忘记登出或清理浏览器时。
6. 无法确保设备和网络变化
- IP地址、设备等环境因素没有变化:一些 Token 通常会包含用户设备、IP 地址等信息来防止 Token 被滥用。如果 Token 长期不变,那么即使用户的网络环境发生了变化,系统也无法感知。这将导致 Token 在不可信的环境中继续使用,增加了安全风险。
7. 用户体验不佳
- 无法提供个性化内容更新:长期不变的 Token 可能导致系统无法捕捉用户状态的实时变化,从而影响个性化内容推荐或提示用户更新信息的能力。
- 会话管理不灵活:如果用户希望在不同设备上管理会话(如在一个设备上登出时使另一个设备上的 Token 失效),长期不变的 Token 可能无法支持这种场景。
逻辑+代码实现
可以采用双拦截器实现,第一个拦截器是自定义的,而这个拦截器总是返回true,第二个拦截器使用satoken的拦截器做一些登录或者权限的认证。
代码实现
package fun.acowbo.config;import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @author <a href="https://acowbo.fun">acowbo</a>* @since 2024/8/27*/
@Slf4j
@Component
public class CustomInterceptor implements HandlerInterceptor{@Value("${sa-token.token-name}")private String tokenName;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {return true;}long tokenActivityTimeout = StpUtil.getTokenActivityTimeout();log.info("tokenActivityTimeout:{}", tokenActivityTimeout);long tokenTimeout = StpUtil.getTokenTimeout();if (tokenActivityTimeout > 0){response.setHeader(tokenName, StpUtil.getTokenValue());response.setHeader("Access-Control-Expose-Headers", tokenName);}if (tokenActivityTimeout < 0 && tokenTimeout > 0){// 首先要让token活跃StpUtil.updateLastActivityToNow();String loginId = (String) StpUtil.getLoginId();// 先退出,否则之前的token还能用StpUtil.logout(loginId);// 重新设置token,这里仅仅是为了安全,否则始终token是一个值StpUtil.login(loginId,new SaLoginModel().setToken(IdUtil.randomUUID()));// 请求头修改token的值,否则在第二个拦截器会报错,因为老的token已经失效了request.setAttribute(tokenName, StpUtil.getTokenValue());// 响应头设置值response.setHeader(tokenName, StpUtil.getTokenValue());response.setHeader("Access-Control-Expose-Headers", tokenName);}return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {}
}
package fun.acowbo.config;import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import javax.annotation.Resource;
import java.util.Arrays;/*** description: sa-token权限配置类** @author <a href="https://acowbo.fun">acowbo</a>* @since 2024/6/7 13:59*/
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {@Value("${excludePath}")private String excludePath;@Resourceprivate CustomInterceptor customInterceptor;@Overridepublic void addCorsMappings(CorsRegistry registry) {// 允许所有路径registry.addMapping("/**")// 允许所有来源.allowedOrigins("*")// 允许的 HTTP 方法.allowedMethods("GET", "POST", "PUT", "DELETE")// 允许的请求头.allowedHeaders("*")// 允许发送 Cookie.allowCredentials(false)// 预检请求的缓存时间.maxAge(3600);}// 注册拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册 Sa-Token 拦截器,校验规则为 StpUtil.checkLogin() 登录校验。registry.addInterceptor(customInterceptor).addPathPatterns("/**").excludePathPatterns(Arrays.asList(excludePath.split(",")));registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin())).addPathPatterns("/**").excludePathPatterns(Arrays.asList(excludePath.split(",")));}
}
拦截器知识补充
在 Spring 框架中,如果定义了多个拦截器,它们的执行顺序是根据它们的注册顺序决定的。具体的执行顺序可以通过以下规则来理解:
1. 注册顺序决定执行顺序
在 Spring 中,拦截器是通过 WebMvcConfigurer
接口中的 addInterceptors
方法进行注册的。多个拦截器会按照它们注册的先后顺序进行调用。
- 拦截器的执行顺序(进入请求时):按照注册顺序依次调用,先注册的拦截器会先执行。
- 拦截器的执行顺序(响应时):响应返回时,拦截器的执行顺序与请求时相反,最后注册的拦截器会最先执行。
示例:
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new FirstInterceptor()).addPathPatterns("/**");registry.addInterceptor(new SecondInterceptor()).addPathPatterns("/**");}
}
在这个例子中:
- 进入请求时:
FirstInterceptor
->SecondInterceptor
- 返回响应时:
SecondInterceptor
->FirstInterceptor
2. 拦截器方法的执行顺序
拦截器的核心方法有以下三个,它们的调用顺序也需要注意:
preHandle
: 在请求处理之前执行。postHandle
: 在请求处理完后(但在视图渲染之前)执行。afterCompletion
: 在视图渲染完成后执行。
当有多个拦截器时:
preHandle
方法按照拦截器的注册顺序执行。postHandle
和afterCompletion
方法则按照相反顺序执行。
3. 优先级控制
如果需要更精确地控制拦截器的顺序,除了按注册顺序,还可以借助其他方法:
- 排序接口:通过实现
Ordered
接口或使用@Order
注解,可以为拦截器明确指定顺序。 - 配置拦截器链的顺序:通过配置文件明确指定拦截器的顺序,也可以使用
InterceptorRegistry
的 API 动态调整顺序。
总结
- 拦截器的执行顺序取决于它们的注册顺序,先注册的拦截器先处理请求,后注册的拦截器先处理响应。
- 可以使用
@Order
注解或实现Ordered
接口来精确控制多个拦截器的执行顺序。
相关文章:

springboot+satoken实现刷新token(值变化)
欢迎来到我的博客,代码的世界里,每一行都是一个故事 🎏:你只管努力,剩下的交给时间 🏠 :小破站 springbootsatoken实现刷新token satoken是什么?支持什么?为什么需要&…...

63.HDMI显示器驱动设计与验证-彩条实验
(1)常见的视频传输接口有三种: VGA 接口、 DVI 接口和 HDMI 接口,目前的显示设备都配有这三种视频传输接口。三类视频接口的发展历程为 VGA→DVI→HDMI。其中 VGA 接口出现最早,只能传输模拟图像信号; 随后…...

安卓13设置删除网络和互联网选项 android13隐藏设置删除网络和互联网选项
总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改4.1修改方法14.2修改方法25.编译6.彩蛋1.前言 有些客户不想让用户修改默认的网络配置,禁止用户进入里面调整网络相关的配置。 2.问题分析 像这个问题,我们有好几种方法去处理,这种需求一般…...
C++的6种构造函数
在 C 中,构造函数是一种特殊的成员函数,用于初始化类对象。在对象创建时自动调用,构造函数的主要作用是分配资源、初始化数据成员等。根据不同的功能和使用场景,C 提供了多种类型的构造函数: 1. 默认构造函数 (Defaul…...
【FE】NPM——概述
NPM基本使用 下载Node 老生常谈,选择LTS版本官网放这里:https://nodejs.cn/download/ 1.镜像配置:镜像源 镜像配置 依赖仓库:版本查看 //不确定仓库有哪些版本,列出指定包的所有版本 npm view <package-name&…...

Clipboard.js实现复制文本到剪贴板功能
一、Clipboard.js简介 Clipboard.js是一个轻量级的实现复制文本到剪贴板功能的JavaScript插件,该插件可以将输入框,文本域,DOM节点元素中的文本内容复制到剪贴板中。 官网地址:Clipboard.js 浏览器兼容性:兼容Chrome、…...

Harbor安装笔记
下载离线安装包 wget https://github.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgz 解压 tar -zxvf harbor-offline-installer-v2.11.1.tgz 复制一份配置文件出来,修改配置 cp harbor.yml.tmpl harbor.yml vim harbor…...

HTTP 1.0 2.0 3.0详解
HTTP HTTP全称超文本传输协议,是一种属于应用层的通信协议。它允许将超文本标记语言文档(HTML)从Web服务器传输到客户端的浏览器。 HTTP报文结构 请求报文结构 请求方法: GET:一般用来请求已被URI识别的资源&#x…...
Python操作TXT文本:从入门到精通
在数字化时代,文本处理成为了许多工作和项目的基础。Python作为一种强大且易学的编程语言,在文本处理方面展现出了无与伦比的优势。本文将通过举例的方式,向读者介绍如何使用Python来操作TXT文本,让您轻松掌握文本处理的精髓。 一、读取TXT文本内容 首先,我们需要学会如…...

开源 AI 智能名片 2+1 链动模式 S2B2C 商城小程序的数据运营策略与价值创造
一、引言 1.1 研究背景 在当今数字化时代,数据运营已成为企业发展的核心驱动力。开源 AI 智能名片 21 链动模式 S2B2C 商城小程序作为一种创新的营销工具,与数据运营紧密相连。该小程序通过集成人工智能、大数据分析等先进技术,能够实时收集…...
ip 地址查看cmd命令
ip 地址查看cmd命令 在不同的操作系统中,查看IP地址的命令可能会有所不同。以下是一些常见操作系统中查看IP地址的命令: Windows: 打开命令提示符(CMD),然后输入 ipconfig 命令。 Linux/Unix: 打开终端࿰…...
力扣9.26
931. 下降路径最小和 给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即…...

HT8731 内置自适应H类升压和防破音功能的10W D类及AB类音频功率放大器
1、特点 防削顶失真功能(防破音,Anti-Clipping Function, ACF) 免滤波器数字调制,直接驱动扬声器 输出功率 10W(VBAT4.2V,RL3Ω,THDN10%, fiN 1kHz) 6W(VBAT3.3~4.2V,RL4Ω,THDN<1%,20-20kHz 全频段) 3W (VBAT3.3~4.2V,RL8Ω, THDN<1%, 20- 20kHz 全频段 VB…...

webpack使用
一、简介 概述 本次使用webpack4进行构建打包 二、webpack 安装webpack、webpack-cli npm install webpack4.2.0 webpack-cli4.2.0 -D 三、loader 加载器概述 raw-loader:加载文件原始内容(utf-8) file-loader:把文件输出…...
高通Android 12 音量API设置相关代码
// 获取当前音量大小public static int getCurrentVolume(Context context) {AudioManager audioManager (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);return audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); // 使用 STREAM_MUSIC 作为示例…...

Qt开发第一讲
一、Qt项目里面有什么? 对各个文件的解释: Empty.pro文件 QT core gui # 要引入的Qt模块,后面学习到一些内容的时候可能会修改这里 #这个文件相当于Linux里面的makefile文件。makefile其实是一个非常古老的技术了。 #qmake搭配.pr…...

详细指南:如何有效解决Windows系统中msvcp140.dll丢失的解决方法
如果你在使用Windows系统时遇到“msvcp140.dll丢失”的错误提示,通常是因为你的计算机上缺少或损坏了msvcp140.dll文件。msvcp140.dll是Microsoft Visual C Redistributable包的一部分,许多应用程序和游戏需要它来正常运行。以下是几种解决msvcp140.dll丢…...
【RabbitMQ】幂等性、顺序性
幂等性 概述 幂等性是数学和计算机科学中某些运算的性质,他们可以被多次应用,而不会改变初始应用的结果。RabbitMQ的幂等性则是指同一条消息,多次消费,对系统的影响是相同的。 一般消息中间件的消息传输保障分为三个层级&#…...
FFmpeg源码:avio_skip函数分析
AVIOContext结构体和其相关的函数分析: FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析 FFmpeg源码:read_packet_wrapper、fill_buffer函数分析 FFmpeg源码:avio_read函数分析 FFmpeg源码ÿ…...

Llama 3.1 技术研究报告-6
6 推理 我们研究了两种主要技术,以使 Llama 3 405B 模型的推理⾼效:(1) 流⽔线并⾏和 (2) FP8 量化。我们已经公开发布了我们的 FP8 量化实现。 6.1 流⽔线并⾏ 当使⽤ BF16 数字表⽰模型参数时,Llama 3 405B 不适合在装有 8 个 Nvidia H1…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...