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 方法按照拦截器的注册顺序执行。
  • postHandleafterCompletion 方法则按照相反顺序执行。

3. 优先级控制

如果需要更精确地控制拦截器的顺序,除了按注册顺序,还可以借助其他方法:

  • 排序接口:通过实现 Ordered 接口或使用 @Order 注解,可以为拦截器明确指定顺序。
  • 配置拦截器链的顺序:通过配置文件明确指定拦截器的顺序,也可以使用 InterceptorRegistry 的 API 动态调整顺序。

总结

  • 拦截器的执行顺序取决于它们的注册顺序,先注册的拦截器先处理请求,后注册的拦截器先处理响应。
  • 可以使用 @Order 注解或实现 Ordered 接口来精确控制多个拦截器的执行顺序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1547244.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

内网穿透的应用-Windows系统安装SeaFile并实现远程访问本地共享文件资料详细教程

文章目录 1. 前言2. SeaFile云盘设置2.1 Owncould的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 下载安装3.2 Cpolar注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4.公网访问测试5.结语 1. 前言 本文主要为大家介绍&#xff0c;如何使用两个简单软件…

【Kotlin 集合概述】可变参数vararg、中缀函数infix以及解构声明(二十)

导读大纲 1.1 使用集合: vararg、infix 调用和解构声明1.1.1 扩展 Java 集合 API1.1.2 vararg: 接受任意数量参数的函数1.1.3 处理pairs: Infix 调用和解构声明 1.1 使用集合: vararg、infix 调用和解构声明 本节将介绍 Kotlin 标准库中用于处理集合的一些函数 同时,还介绍一些…

Vue3+Element-UI Plus登录静态页

<script setup> import {reactive, ref} from "vue";const formRefref() const formModelreactive({username:,password: }) const formRulesreactive({username:[{required:true,message:请输入账号,trigger:blur}],password:[{required:true,message:请输入密…

阳光精机第一大客户双刃剑效应:关联交易引关注,产能利用率忽高忽低

《港湾商业观察》杨丹妮 8月27日&#xff0c;北交所向无锡阳光精机股份有限公司&#xff08;以下简称&#xff1a;阳光精机&#xff09;下发第二轮审核问询函&#xff0c;此前阳光精机于2023年12月29日递表北交所。 阳光精机公司主要生产精密主轴、主辊、弧形导轨等机床功能部…

【数据结构】AVL树相关知识详细梳理

1. AVL树的概念 AVL的全称是Adelson-Velsky-Landis&#xff0c;其名称来源于其发明者Adelson、Velsky和Landis&#xff0c; 是平衡二叉树搜索树。 它的出现是由于二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找…

常见的TTL,RS232,RS485,IIC,SPI,UART之间的联系和区别

简单总结 图片来源 RS232,RS485可参考&#xff0c;IIC&#xff0c;SPI,UART可参考 烧录程序中常听到的一句话就是USB转TTL&#xff0c;但严格来说算是USB传输数据的协议转换成TTL&#xff08;Transistor-Transistor Logic&#xff09;协议传输数据。首先&#xff0c;usb是常见…

15、网络安全合规由来与要素

数据来源&#xff1a;1.网络安全合规由来与要素_哔哩哔哩_bilibili 合规由来 合规&#xff08;Compliance&#xff09;&#xff1a;指服从、顺从和遵从的行为&#xff0c;强调使公司的经营活动与法律、监管及内部规则保持一致。合规涉及公司适应法律法规及社会规范等规则的经营…

[附源码]在线音乐系统+SpringBoot+Vue前后端分离

今天带来一款优秀的项目&#xff1a;在线音乐系统源码 。 系统采用的流行的前后端分离结构&#xff0c;内含功能包括 "管理后台"&#xff0c;“用户端”&#xff0c;“评论系统”&#xff0c;“歌手&#xff0c;歌曲管理”&#xff0c;“用户系统”,"统计"…

bugku-头等舱

根据题目提示&#xff0c;查看请求头试一下&#xff0c; 得到flag&#xff0c;直接提交

【JavaScript】LeetCode:56-60

文章目录 56 路径总和Ⅲ57 二叉树的最近公共祖先58 二叉树中的最大路径59 岛屿数量60 腐烂的橘子 56 路径总和Ⅲ 递归遍历每个节点所有可能的路径。pathSum()&#xff1a;返回所有节点满足条件的路径数目&#xff0c;traversal()&#xff1a;返回当前遍历节点满足条件的路径数目…

CloudMusic:免费听歌

本文所涉及所有资源均在 传知代码平台可获取。 目录 概述 演示效果 视频演示 图片展示 核心逻辑 获取歌曲图片 提取搜索结果 使用方式 部署方式 Docker部署1 构建镜像 Web站点部署2 附件下载 概述 CloudMusic是一款全网歌曲免费听的web项目&#xff0c;无需任何数据库&#x…

19、网络安全合规复盘

数据来源&#xff1a;5.网络安全合规复盘_哔哩哔哩_bilibili

【Java】异常处理 —— Throwable 及其应用

通过一张图来展示Throwable类的继承体系&#xff0c;如图2所示。 图2 Throwable异常体系结构图 ● Error类称为错误类&#xff0c;它表示Java运行时产生的系统内部错误或资源耗尽的错误&#xff0c;是比较严重的&#xff0c;仅靠修改程序本身是不能恢复执行的&#xff0c;例如…

3D建模软件 | Blender v4.2.2 绿色版

Blender是一款功能强大的免费开源3D创作套件&#xff0c;适用于创建3D可视化效果&#xff0c;如静态图像、3D动画、视觉特效以及视频编辑。Blender以其跨平台兼容性、高效内存管理、统一的工作流程和活跃的社区支持而受到独立艺术家和小型工作室的青睐。 它提供了从建模、渲染…

Ubuntu下安装向日葵:闪退

下载 https://sunlogin.oray.com/download 初次安装 $ sudo dpkg -i SunloginClient_15.2.0.63064_amd64.deb 正在选中未选择的软件包 sunloginclient。 (正在读取数据库 ... 系统当前共安装有 234281 个文件和目录。) 准备解压 SunloginClient_15.2.0.63064_amd64.deb ..…

使用bat命令在没有java的环境下启动jar包

使用bat命令在没有java的环境下启动jar包 先看一下目录下面的文件 里面有三个比较重要的文件 clean.bat&#xff1a;用于清除占用程序的端口 一键启动_x64.bat&#xff1a;用于启动全部的项目 jre8_win64&#xff1a;用于jar所需要的java环境 注意事项&#xff1a; 关于jar…

MySQL 中优化 COUNT()查询的实用指南

在 MySQL 数据库的使用中&#xff0c;我们经常会用到 COUNT()函数来统计行数或满足特定条件的行数。然而&#xff0c;在处理大规模数据时&#xff0c;COUNT()查询可能会变得非常缓慢&#xff0c;影响数据库的性能。那么&#xff0c;如何在 MySQL 中优化 COUNT()查询呢&#xff…

Redis一些简单通用命令和认识常用数据类型和编码方式

通用命令 get() / set() 这是Redis中两个最为核心的命令。 set插入 这里的key 和 value都是字符串&#xff0c;我们可以加双引号 或者单引号&#xff0c;或者不加。 get查找 如果查询的key值不存在&#xff0c;那么会返回一个 nil &#xff0c;也就是代表空 在Redis中命令…

【C++位图】构建灵活的空间效率工具

目录 位图位图的基本概念如何用位图表示数据位图的基本操作setresettest 封装位图的设计 总结 在计算机科学中&#xff0c;位图&#xff08;Bitmap&#xff09;是一种高效的空间管理数据结构&#xff0c;广泛应用于各种场景&#xff0c;如集合操作、图像处理和资源管理。与传统…

什么是开放式耳机?具有什么特色?非常值得入手的蓝牙耳机推荐

开放式耳机是当下较为热门的一种耳机类型。它具有以下特点&#xff1a; 设计结构&#xff1a; 呈现开放式的构造&#xff0c;不会完全堵住耳道。如此一来&#xff0c;外界声音能够较容易地被使用者听到&#xff0c;在使用耳机时可以保持对周围环境的察觉。比如在户外&#xf…