satoken的奇奇怪怪的错误

发了 /user/getBrowseDetail和/user/getResponDetail,但为什么进入handle里面有三次?且第一次的handle类型是AbstractHandleMapping$PreFlightHttpRequestHandler@xxx,这一次进来的时候flag为false,StpUtils.checkLogin抛出了异常
第二次进来的时候handle的类型为com.example.backend.controller.UserController#getBrowseDetail
这次flag为true,且StpUtils.checkLogin无异常
第三次进来的时候handle的类型为com.example.backend.controller.UserController#getResponseDetail
这次flag为true,且StpUtils.checkLogin无异常

@Overridepublic void addInterceptors(InterceptorRegistry registry){log.info("注册 SaToken 拦截器...");registry.addInterceptor(new SaInterceptor(handle->{ Boolean flag = StpUtil.isLogin();StpUtil.checkLogin();})).addPathPatterns("/question/check", "/user/**", "/chatAI/cancel").excludePathPatterns("/login", "/register"); // 根据需要排除某些路径}

从你的描述来看,问题的根本原因在于 CORS 预检请求(Preflight Request) 的存在。这是浏览器在发送跨域请求时的一种安全机制,尤其是当你使用 PUTDELETEOPTIONS 等方法,或者带有自定义头部时,浏览器会先发送一个 OPTIONS 请求作为预检请求,以确认服务器是否允许实际的请求。


问题分析

  1. 第一次请求:AbstractHandleMapping$PreFlightHttpRequestHandler
    • 这是浏览器发送的 CORS 预检请求,类型为 OPTIONS
    • 预检请求的目的是检查服务器是否允许跨域请求。
    • 由于这是一个 OPTIONS 请求,Spring MVC 会由 AbstractHandleMapping$PreFlightHttpRequestHandler 处理,而不是你的控制器方法。
    • 在拦截器中,StpUtil.isLogin()StpUtil.checkLogin() 会被调用,但由于预检请求没有携带用户的登录信息(如 Token),因此会抛出异常。

  2. 第二次请求:UserController#getBrowseDetail
    • 这是实际的跨域请求,浏览器在收到预检请求的允许响应后,会发送真实的请求(如 GETPOST)。
    • 此时,用户的登录信息(如 Token)会被正确传递,StpUtil.isLogin()StpUtil.checkLogin() 可以正常工作。

  3. 第三次请求:UserController#getResponseDetail
    • 如果你同时触发了多个请求(例如前端代码中有多个并发请求),可能会看到类似的日志。
    • 每个请求都会经过拦截器,但由于它们是真实的请求,StpUtil.checkLogin() 不会抛出异常。


解决方案

为了避免拦截器对 CORS 预检请求的处理,可以在拦截器中添加对 OPTIONS 请求的特殊处理逻辑,直接放行 OPTIONS 请求。

修改拦截器代码
@Override
public void addInterceptors(InterceptorRegistry registry) {log.info("注册 SaToken 拦截器...");registry.addInterceptor(new SaInterceptor(handle -> {// 如果是 OPTIONS 请求,直接放行if ("OPTIONS".equalsIgnoreCase(handle.getRequest().getMethod())) {return;}// 检查用户是否登录Boolean flag = StpUtil.isLogin();StpUtil.checkLogin(); // 如果未登录,会抛出异常})).addPathPatterns("")// 这里写你的自己的.excludePathPatterns(""); //这里写你自己的  根据需要排除某些路径
}
关键点

handle.getRequest().getMethod():获取当前请求的 HTTP 方法。
"OPTIONS".equalsIgnoreCase(...):判断是否为 OPTIONS 请求。
直接放行:如果是 OPTIONS 请求,直接返回,不执行后续的登录检查逻辑。


进一步优化

如果你希望更优雅地处理 CORS 预检请求,可以结合 Spring 的 CorsConfiguration 来全局配置 CORS,而不是依赖拦截器来处理。

添加 CORS 配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 允许跨域的路径.allowedOrigins("*") // 允许的来源(可以改为具体的域名).allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的 HTTP 方法.allowedHeaders("*") // 允许的请求头.allowCredentials(true) // 是否允许发送凭证(如 Cookie、Token).maxAge(3600); // 预检请求的有效期(秒)}
}
优点

• 通过 CorsConfiguration 处理跨域问题,避免拦截器对 OPTIONS 请求的干扰。
• 更加清晰和规范地管理跨域请求。


总结

问题原因:CORS 预检请求(OPTIONS 方法)触发了拦截器的逻辑,导致异常。
解决方案

  1. 在拦截器中添加对 OPTIONS 请求的放行逻辑。
  2. 使用 Spring 的 CorsConfiguration 全局配置 CORS,避免拦截器处理 OPTIONS 请求。
    推荐方案:使用 CorsConfiguration,因为它更符合 Spring 的设计理念,并且可以更好地管理跨域问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【KWDB 创作者计划】_上位机知识篇---SDK

文章目录 前言一、SDK的核心组成API(应用程序接口)库文件(Libraries)开发工具文档与示例依赖项与环境配置二、SDK的作用简化开发流程确保兼容性与稳定性加速产品迭代功能扩展与定制三、SDK的典型应用场景硬件设备开发操作系统与平台云服务与API集成游戏与图形开发四、SDK与…

golang处理时间的包time一次性全面了解

本文旨在对官方time包有个全面学习了解。不钻抠细节,但又有全面了解,重点介绍常用的内容,一些低频的可能这辈子可能都用不上。主打一个花最少时间办最大事。 Duration对象: 两个time实例经过的时间,以长度为int64的纳秒来计数。 常见的durati…

PyCharm Flask 使用 Tailwind CSS 配置

使用 Tailwind CSS 步骤 1:初始化项目 在 PyCharm 终端运行:npm init -y安装 Tailwind CSS:npm install -D tailwindcss postcss autoprefixer初始化 Tailwind 配置文件:npx tailwindcss init这会生成 tailwind.config.js。 步…

【英语语法】基本句型

目录 前言一:主谓二:主谓宾三:主系表四:主谓双宾五:主谓宾补 前言 英语基本句型是语法体系的基石,以下是英语五大基本句型。 一:主谓 结构:主语 不及物动词 例句: T…

隔离DCDC辅助电源解决方案与产品应用科普

**“隔离”与“非隔离的区别** 隔离: 1、AC-DC,也叫“一次电源”,人可能会碰到的应用场合,起安全保护作用; 2、为了抗干扰,通过隔离能有效隔绝干扰信号传输。 非隔离: 1、“安全特低电压&#…

DS-SLAM 运动一致性检测的源码解读

运动一致性检测是Frame.cc的Frame::ProcessMovingObject(const cv::Mat &imgray)函数。 对应DS-SLAM流程图Moving consistency check的部分 把这个函数单独摘出来&#xff0c;写了一下对两帧检测&#xff0c;查看效果的程序&#xff1a; #include <opencv2/opencv.hpp…

安全测试的全面知识体系及实现路径

以下是安全测试的全面知识体系及实现路径,结合最新工具和技术趋势(截至2025年): 一、安全测试核心类型与工具 1. 静态应用安全测试(SAST) 知识点: 通过分析源代码、字节码或二进制文件识别漏洞(如SQL注入、缓冲区溢出)支持早期漏洞发现,减少修复成本,适合白盒测试场…

GPT-4o Image Generation Capabilities: An Empirical Study

GPT-4o 图像生成能力:一项实证研究 目录 介绍研究背景方法论文本到图像生成图像到图像转换图像到 3D 能力主要优势局限性与挑战对比性能影响与未来方向结论介绍 近年来,图像生成领域发生了巨大的变化,从生成对抗网络 (GAN) 发展到扩散模型,再到可以处理多种模态的统一生成架…

Redis之全局唯一ID

全局ID生成器 文章目录 全局ID生成器一、全局ID生成器的定义定义核心作用 二、全局ID生成器需满足的特征1. 唯一性&#xff08;Uniqueness&#xff09;​2. 高性能&#xff08;High Performance&#xff09;​3. 可扩展性&#xff08;Scalability&#xff09;​4. 有序性&#…

nginx中的代理缓存

1.缓存存放路径 对key取哈希值之后&#xff0c;设置cache内容&#xff0c;然后得到的哈希值的倒数第一位作为第一个子目录&#xff0c;倒数第三位和倒数第二位组成的字符串作为第二个子目录&#xff0c;如图。 proxy_cache_path /xxxx/ levels1:2 2.文件名哈希值

静态时序分析STA——8.1 时序检查(建立时间检查)

文章目录 一、时序路径组二、建立时间检查1. 触发器到触发器路径1&#xff09;时钟单元UCKBUF0的延迟计算2&#xff09;时钟源延迟&#xff08;clock source latency&#xff09; 2. 输入到触发器路径1) 虚拟时钟的输入路径2) 具有实际时钟的输入路径 3. 触发器到输出路径4. 输…

了解高速设计的信号完整性仿真

高速设计需要精确的信号传输&#xff0c;以确保最佳性能。信号完整性差会导致关键应用中的误码、数据损坏甚至系统故障等问题。介电常数、损耗角正切和插入损耗等因素会显著影响信号质量。通过使用信号完整性仿真&#xff0c;您可以及早发现并解决这些挑战。这种主动方法有助于…

RAGFlowwindows本地pycharm运行

Python环境准备 1. 安装pipx。如已经安装&#xff0c;可跳过本步骤&#xff1a; python -m pip install --user pipxpython -m pipx ensurepath## 验证安装pipx --version2. 安装 uv。如已经安装&#xff0c;可跳过本步骤&#xff1a; pipx install uv ## 设置为阿里云 PyPI…

STM32-FreeRTOS的详细配置

配置FreeRTOS 原文链接&#xff1a;https://ydamooc.github.io/posts/c9defcd/ 1.1 下载FreeRTOS 打开FreeRTOS官网&#xff1a;https://www.freertos.org/ 点击下载&#xff0c;并且选择"FreeRTOS 202212.01"版本&#xff0c;再点击Download按钮下载官方的资源包…

Linux笔记---动静态库(原理篇)

1. ELF文件格式 动静态库文件的构成是什么样的呢&#xff1f;或者说二者的内容是什么&#xff1f; 实际上&#xff0c;可执行文件&#xff0c;目标文件&#xff0c;静态库文件&#xff0c;动态库文件都是使用ELF文件格式进行组织的。 ELF&#xff08;Executable and Linkable…

HVV-某田相关经历

一、背景 本次项目为期两周&#xff0c;由集团主导招募攻击队员对集团下属及其子公司进行的攻防演练。本次项目主导研判分析应急排查内部Nday发掘。 二、研判分析 2.1、帆软V10 漏洞概述 帆软 V10 及 V11 版本报表软件存在反序列化漏洞&#xff0c;攻击者可利用该漏洞使用…

AI与物联网的深度融合:开启智能生活新时代

在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;和物联网&#xff08;IoT&#xff09;作为两大前沿技术&#xff0c;正在加速融合&#xff0c;为我们的生活和工作带来前所未有的变革。这种融合不仅提升了设备的智能化水平&#xff0c;还为各行各业带来了新的机…

Linux `init` 相关命令的完整使用指南

Linux init 相关命令的完整使用指南—目录 一、init 系统简介二、运行级别&#xff08;Runlevel&#xff09;详解三、常用 init 命令及使用方法1. 切换运行级别2. 查看当前运行级别3. 服务管理4. 紧急模式&#xff08;Rescue Mode&#xff09; 四、不同 Init 系统的兼容性1. Sy…

UNet 改进(12):UNet with ECA (Efficient Channel Attention) 网络

详解 下面将详细解析这个实现了ECA注意力机制的UNet网络代码。 1. 代码概述 代码实现了一个带有Efficient Channel Attention (ECA)模块的UNet网络架构。 UNet是一种常用于图像分割任务的编码器-解码器结构网络,而ECA模块则是一种轻量级的通道注意力机制,可以增强网络对重…

视频监控EasyCVR视频汇聚平台接入海康监控摄像头如何配置http监听功能?

一、方案概述 本方案主要通过EasyCVR视频管理平台&#xff0c;实现报警信息的高效传输与实时监控。海康监控设备能通过HTTP协议将报警信息发送至指定的目的IP或域名&#xff0c;而EasyCVR平台则可以接收并处理这些报警信息&#xff0c;同时提供丰富的监控与管理功能&#xff0…