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.pswp.cn/diannao/79327.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79327.shtml
英文地址,請注明出處:http://en.pswp.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…