集成sa-token前后端分离部署配置corsFliter解决跨域失效的真正原因

文章目录

  • 1.前言
  • 2.问题复现
  • 3.解决方法
    • 3.1 方式一:后端修改CorsFilter源码
    • 3.2 方式二:前端禁用或移除浏览器referrer-policy引用者策略
  • 4.总结

1.前言

    缘由请参看下面这篇文章:sa-token前后端分离解决跨域的正确姿势

https://mp.weixin.qq.com/s/96WbWL28T5_-xzyCfJ7Stg
https://blog.csdn.net/qq_34905631/article/details/140233780?spm=1001.2014.3001.5501

    这篇文章虽然经过n多次尝试找到了正确的姿势,但是问题的根本原因没有找到,然后我就经过一些思考和探索,我想这个跨域能不能在本地模拟出来,然后起就去找了项目前端人员老王,然后确实模拟出本地跨域,在项目中将之前sa-token前后端分离解决跨域的正确姿势文章中的SimpleCORSFilter注释之后进行了问题复现。

2.问题复现

     spring5.2.15.RELEASE官方mvc的跨域配置如下:

https://docs.spring.io/spring-framework/docs/5.2.15.RELEASE/spring-framework-reference/web.html#mvc-cors-intro

    按照上面链接官方的一种方式,然后新增了一个CustomCorsFilter类如下:

package xxxx.config;import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomCorsFilter extends CorsFilter {public CustomCorsFilter() {super(corsConfigurationSource());}private static CorsConfigurationSource corsConfigurationSource() {CorsConfiguration configuration = new CorsConfiguration();configuration.addAllowedOrigin("*"); // 允许访问的域名,例如 http://localhost:8080configuration.addAllowedHeader("*"); // 允许所有请求头configuration.addAllowedMethod("*"); // 允许所有请求方法configuration.setAllowCredentials(true);UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", configuration);return source;}}

    该CustomCorsFilter的配置写法我搞的一个项目中配置验证过是有效的,但是在最近做的一个项目中使用这个CustomCorsFilter类配置到项目中解决跨域缺没有用,难道是这种配置失效了吗?在上面sa-token前后端分离解决跨域的正确姿势文章中配置了CustomCorsFilter类验证确实是失效了,这个问题真的是让人百思不得其解,当我在项目中重新配置好CustomCorsFilter类之后(SimpleCORSFilter需要注释,因为这个SimpleCORSFilter进过验证时可以行的),紧接着把项目本地跑起来之后,前端模拟跨域请求,我在CorsFilter类的如下代码打上断点:

   @Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,FilterChain filterChain) throws ServletException, IOException {CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);boolean isValid = this.processor.processRequest(corsConfiguration, request, response);//关键就是这里,在这里打上断点if (!isValid || CorsUtils.isPreFlightRequest(request)) {return;}filterChain.doFilter(request, response);}

    CorsUtils.isPreFlightRequest方法上也打上断点:

	public static boolean isPreFlightRequest(HttpServletRequest request) {return (HttpMethod.OPTIONS.matches(request.getMethod()) &&request.getHeader(HttpHeaders.ORIGIN) != null &&request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null);}

    然后断点截图如下:

    登录接口是一个http加域名的复杂跨域请求会发送一个预检测请求(OPTIONS请求)

cors调试图片2

    在集成了sa-token的项目中OncePerRequestFilter的doFilterInternal方法打上断点,发现有如下过滤器:

cors调试图片2

    可以看到上面我们自定一的CustomCorsFilter是在最先执行的,sa-token相关的两个filter:saPathCheckFilterForServlet和SaServletFilter都是后面才执行的,所以之前的其他猜想都得到了很好的证实,当断点走到下面这里CorsFilter的doFilterInternal方法中:

       //关键就是这里,在这里打上断点if (!isValid || CorsUtils.isPreFlightRequest(request)) {return;}

    问题就出在如下代码:

CorsUtils.isPreFlightRequest(request)

    这行代码返回了true,就return了,后面的所有过滤器都没有执行,所以请求不到接口,浏览器还是在报跨域的问题,然后我就调试了CorsUtils.isPreFlightRequest(request)这行代码,发现是复杂请求跨域发了预检测请求(OPTIONS请求)之后Orgin会被设置了一个莫名奇妙的是:

http://localhost:3000

    这个就很奇怪了,然后我就找了前端同事老王帮看了下,这个值是哪里设置的,然后发现如下:

cors调试图片3

    前端没有设置Orgin,只是设置了如下参数:

//设置axios跨域访问
axios.defaults.withcredentials = true // 设置cross跨域 并设置访问权限 允许跨域携带cookie信息axios.defaults.crossDomain=true //设置axios跨域的配置

    上面的图片只有一个Referer的值跟Orgin的值不谋而合,难道这真的只是一个巧合,于是我参看了如下文章:

https://blog.csdn.net/qq_55316925/article/details/128571809

    给我很多的思路,那我想了一下,居然这样,后端配置的CustomCorsFilter是生效了的,那可不可以改CorsFilter源码,于是就尝试了下面两种方式,进过我和前端老王的验证,这两种方式都是可行的,任选一种都是可以解决cors跨域问题。

3.解决方法

3.1 方式一:后端修改CorsFilter源码

    后端修改CorsFilter源码

    在项目下src.main.java下新增一个org.springframework.web.filter的包

    然后将CorsFilter的源码拷贝出来,放到上面新建的这个org.springframework.web.filter的包下,就可以修改CorsFilter的源码了,

/** Copyright 2002-2019 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.web.filter;import java.io.IOException;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.util.Assert;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.CorsProcessor;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.DefaultCorsProcessor;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;/*** {@link javax.servlet.Filter} that handles CORS preflight requests and intercepts* CORS simple and actual requests thanks to a {@link CorsProcessor} implementation* ({@link DefaultCorsProcessor} by default) in order to add the relevant CORS* response headers (like {@code Access-Control-Allow-Origin}) using the provided* {@link CorsConfigurationSource} (for example an {@link UrlBasedCorsConfigurationSource}* instance.** <p>This is an alternative to Spring MVC Java config and XML namespace CORS configuration,* useful for applications depending only on spring-web (not on spring-webmvc) or for* security constraints requiring CORS checks to be performed at {@link javax.servlet.Filter}* level.** <p>This filter could be used in conjunction with {@link DelegatingFilterProxy} in order* to help with its initialization.** @author Sebastien Deleuze* @since 4.2* @see <a href="https://www.w3.org/TR/cors/">CORS W3C recommendation</a>*/
public class CorsFilter extends OncePerRequestFilter {private final CorsConfigurationSource configSource;private CorsProcessor processor = new DefaultCorsProcessor();/*** Constructor accepting a {@link CorsConfigurationSource} used by the filter* to find the {@link CorsConfiguration} to use for each incoming request.* @see UrlBasedCorsConfigurationSource*/public CorsFilter(CorsConfigurationSource configSource) {Assert.notNull(configSource, "CorsConfigurationSource must not be null");this.configSource = configSource;}/*** Configure a custom {@link CorsProcessor} to use to apply the matched* {@link CorsConfiguration} for a request.* <p>By default {@link DefaultCorsProcessor} is used.*/public void setCorsProcessor(CorsProcessor processor) {Assert.notNull(processor, "CorsProcessor must not be null");this.processor = processor;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,FilterChain filterChain) throws ServletException, IOException {CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);boolean isValid = this.processor.processRequest(corsConfiguration, request, response);//修改的源码是将CorsUtils.isPreFlightRequest(request)这行代码移除,就是因为复杂请求跨域发了预检测请求,浏览器的referrer-policy引用者策略会携带一个值,后端处理之后会将这个值赋值给请求头的Orgin属性上,移除这行代码之后就可以正常访问到登录接口了,前端也没有报跨域了。if (!isValid) {return;}filterChain.doFilter(request, response);}}

3.2 方式二:前端禁用或移除浏览器referrer-policy引用者策略

    前端新增如下代码 :禁用或者是移除referrer-policy`这个引用者策略

https://blog.csdn.net/qq_49810363/article/details/111036180

    新增代码如下:

<meta name="referrer" content="never">

cors调试图片4

    浏览器的referrer-policy引用者策略,也是为了安全考虑,我使用的浏览器是chrome浏览器

4.总结

    经过不断地尝试和摸索之后,对这个在项目中集成了sa-token后部署出现cors跨域的问题,总的来说是cors跨域协议的规范不允许这种操作,在加上浏览器和后端的解决库都不允许不遵循cors跨域协议的规范的请求操作,所以可以使用sa-token前后端分离解决跨域的正确姿势文章里面的方法,配置一个SimpleCORSFilter,对参数都写具体,处理预检测请求返回200状态码,或者使用本篇文章的这两种方式的任意一种都可以解决cors跨域的问题,本文的解决方法是我经过亲自打断点复现跨域请求之后debug出来的解决方法,如果你相信可以按照本文的方法,本地复现跨域请求然后dubug打断点,看一下是不是corsFilter的CorsUtils.isPreFlightRequest(request)这行代码的问题,总的来说,这个cors的跨域问题是浏览器要背的一个大锅,简单请求corsFilter是不会失效的,复杂请求发了预检测请求(OPTIONS请求),由于浏览器的referrer-policy引用者策略会携带一个值,后端处理之后会将这个值赋值给请求头的Orgin属性上,导致corsFilter的CorsUtils.isPreFlightRequest(request)这行代码返回true之后就return了,导致后面的一系列的Filter的doFilter没有执行到,也没有访问到后端的接口,而前端浏览器页面还在报跨域的问题,这个问题说实话是真的坑啊。https的方式跨域不行,因为https是监听443端口,是需要证书的,这个我猜测是要配置证书才可以的,本文洗白了集成sa-token之后会导致corsFilter配置失效的罪名啊,网上千篇一律的文章都没有本文的这种情况下的解决方法的,应该来说还是首创吧,创作不易,请尊重作者原创,请不要抄袭当做原创,请转载添加上原创出处,本次分享到此结束,希望我的分享对你有所启发和帮助,请一键三连,么么哒!

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

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

相关文章

桌面记笔记的软件:能加密的笔记app

在日常生活和工作中&#xff0c;很多人都有记笔记的习惯。无论是记录会议要点、学习心得&#xff0c;还是生活中的点滴灵感&#xff0c;笔记都是我们不可或缺的好帮手。然而&#xff0c;传统的纸笔记录方式逐渐不能满足现代人的需求&#xff0c;因为纸质笔记不易保存、查找困难…

STM32 - SPI硬件外设

配合我的上一篇SPI ​​​​​​通信 协议-CSDN博客一起理解更佳&#xff0c;本文后看 SPI 是由摩托罗拉(Motorola)公司开发的全双工同步串行总线&#xff0c;是 MCU 和外围设备之间进行通信的同步串行端口。主要应用在EEPROM、Flash、RTC、ADC、网络控制器、MCU、DSP以及数字信…

网上怎么样可以挣钱,分享几种可以让你在家赚钱的兼职项目

当今社会&#xff0c;压力越来越大&#xff0c;工作、家庭、生活等等&#xff0c;方方面面都需要钱&#xff0c;仅靠一份工作赚钱&#xff0c;已经很难满足我们的需求。所以很多人都会尝试做一些副业&#xff0c;兼职来补贴家用。 现在呢&#xff0c;有很多人都想在网上赚钱&am…

微型导轨如何提升数控机床的稳定性?

数控机床是加工设备中常用的机床&#xff0c;精度和稳定性是衡量数控机床性能的重要指标。而微型导轨作为数控机床中重要的传动元件&#xff0c;数控机床与其具体结构性能是密不可分的&#xff0c;那么微型导轨如何提高数控机床的稳定性呢&#xff1f; 1、微型导轨通过采用先进…

githup开了代理push不上去

你们好&#xff0c;我是金金金。 场景 git push出错 解决 cmd查看 git config --global http.proxy git config --global https.proxy 如果什么都没有&#xff0c;代表没设置全局代理&#xff0c;此时如果你开了代理&#xff0c;则执行如下&#xff0c;设置代理 git con…

关于SQL NOT IN判断失效的情况记录

1.准备测试数据 CREATE TABLE tmp_1 (val integer);CREATE TABLE tmp_2 (val integer, val2 integer);INSERT INTO tmp_1 (val) VALUES (1); INSERT INTO tmp_1 (val) VALUES (2); INSERT INTO tmp_2 (val) VALUES (1); INSERT INTO tmp_2 (val, val2) VALUES (NULL,0);2.测…

什么是静态住宅代理?一文看懂它

静态住宅代理&#xff08;也称为 ISP 代理&#xff09;是最流行的代理类型之一。它们也是隐藏身份和在线匿名的最佳方式之一。但是您需要了解它们什么&#xff1f;是什么让它们如此特别&#xff1f;为什么您要使用住宅代理而不是仅仅使用常规代理服务&#xff1f;如果你感兴趣&…

exel带单位求和,统计元素个数

如果exel表格中&#xff0c;如果数据有单位&#xff0c;无法直接用 自动求和 直接求和。如下图所示&#xff0c;求和结果为0&#xff0c;显然不是我们想要的。 用下面的公式求和&#xff0c;单位不是“个”的时候记得替换单位。统计范围不是“C1:C7”也记得换一下啊&#xff01…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

BFS:边权相同的最短路问题

一、边权相同最短路问题简介 二、迷宫中离入口最近的出口 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:const int dx[4]{1,-1,0,0};const int dy[4]{0,0,1,-1};int nearestExit(vector<vector<char>>& maze, vector<int>& e…

js函数扩展内容---多参数,函数属性,字符串生成函数

1.多参数 在js中&#xff0c;Math.max()方法可以接受任意数量的参数&#xff0c; Math.max(1,2,3,4);//4 Math.max(1,2,3,4,5,6,7,8,9,10)//10 在max方法里面有一个rest参数&#xff0c;它接受了所有参数全部合成到了一个number数组里面&#xff0c; function rest(a,b,...a…

12 - matlab m_map地学绘图工具基础函数 - 在地图上绘制矢量场m_vec函数和绘制风羽图的m_windbarb函数

12 - matlab m_map地学绘图工具基础函数 - 在地图上绘制矢量场函数m_vec和绘制风羽图的函数m_windbarb 0. 引言1. 关于m_vec2. 关于m_windbarb3. 总结 0. 引言 本篇介绍下m_map中绘制矢量场的函数&#xff08;m_vec&#xff09;和地图上绘制风羽图的函数m_windbarb。 1. 关于m…

QT信号量与槽

文章目录 概述用系统生成新增一个信号量和槽代码方式信号量和槽的宏信号量和槽都用函数地址lamda表达式函数指针 槽和信号量函数信号量槽 小结 概述 这个内容是QT独有的&#xff0c;写的挺有意义的。之前写过一篇QT slots的函数&#xff0c;思来想去&#xff0c;觉得不是那么有…

python-22-零基础自学python-数据分析基础 打开文件 读取文件信息

学习内容&#xff1a;《python编程&#xff1a;从入门到实践》第二版 知识点&#xff1a; 读取文件 、逐行读取文件信息等 练习内容&#xff1a; 练习10-1:Python学习笔记 在文本编辑器中新建一个文件&#xff0c;写几句话来总结一下你至此学到的Python知识&#xff0c;其中…

考CISP,不要踩坑的几点建议

当你立志要在信息安全领域闯出一片天&#xff0c;可能多少都会听行内人说&#xff0c;搞本CISP。但这个认证究竟该怎么拿&#xff1f;需要培训吗&#xff1f;培训又是怎么一回事&#xff1f;价格如何&#xff1f;还有&#xff0c;什么时候开始准备最好&#xff1f;这些问题可能…

【实习问题记录】Nodeclub本地部署

问题描述 在按照官方网站给出的教程一步一步操作以后发现出现以下报错&#xff1a; 问题分析 显示连接不上mongodb&#xff0c;分析报错可能是因为版本不匹配导致的&#xff0c;查看安装的mongodb版本发现是7.0.4&#xff0c;与目标版本不匹配&#xff0c;同时查看mongodb官…

我们所熟知的meme梗图也可以用AI生成了,老外都玩坏了。

meme梗图不知道大家看到过嘛&#xff1f;相信你们看见下面的图你就会大叫“卧槽”&#xff0c;原来是这种图&#xff0c;我以前经常狂刷不止&#xff0c;太有趣了。 其实meme是一个网络流行语&#xff0c;可译为模因。在大众非学术范围内也可翻译为我们所熟知的“梗”。其中“表…

SDK环境的安装(测试使用)

1、安装 将文件解压至目录,我的目录为:D:\Program Files\Android 解压后如下: 下载链接如下: sdk下载 提取码见文章最后: 2、配置环境 1、在环境变量中,选择系统变量,点击新建。 变量名:ANDROID_HOME 变量值:“你自己的android-sdk安装路径” (例如我的:D:\Pro…

CSS--表格自适应宽度并设置最小宽度

原文网址&#xff1a;CSS--表格自适应宽度并设置最小宽度_IT利刃出鞘的博客、-CSDN博客 简介 本文介绍怎样让HTML的表格自适应宽度。 Java技术星球&#xff1a;way2j.com 问题描述 默认样式下&#xff0c;表格会出现某一列很窄的情况&#xff1a; 代码&#xff1a; <h…

Redission 解锁异常:attempt to unlock lock, not locked by current thread by node id

标题&#xff1a;解锁异常&#xff1a;Redission中的"attempt to unlock lock, not locked by current thread by node id"问题分析与解决方案 在分布式系统中&#xff0c;锁是常用的同步机制&#xff0c;用于保护共享资源&#xff0c;避免并发冲突。Redission是一个…