集成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:8080
        configuration.addAllowedHeader("*"); // 允许所有请求头
        configuration.addAllowedMethod("*"); // 允许所有请求方法
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

}

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

   @Override
	protected 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;
	}


	@Override
	protected 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配置失效的罪名啊,网上千篇一律的文章都没有本文的这种情况下的解决方法的,应该来说还是首创吧,创作不易,请尊重作者原创,请不要抄袭当做原创,请转载添加上原创出处,本次分享到此结束,希望我的分享对你有所启发和帮助,请一键三连,么么哒!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【算法】二叉树-迭代法实现前后中序遍历

递归的实现就是:每一次递归调用都会把函数的局部变量&#xff0c;参数值和返回地址等压入调用栈中&#xff0c;然后递归返回的时候&#xff0c;从栈顶弹出上一次递归的各项参数&#xff0c;这就是递归为什么可以返回上一层位置的原因 可以用栈实现二叉树的前中后序遍历 1. 前序…

base SAS programming学习笔记(functions)

1.SAS function 分类&#xff1a; 计算描述统计量的函数&#xff1a; 举例如下&#xff1a;avgscoremean(exam1,exam2,exam3) 2.function 基本格式 function-name(argument1,argument2,......<argumentn>&#xff09; argument可以如下&#xff1a;变量名&#xff1b;常…

redis学习(009 实战:黑马点评:缓存穿透、缓存雪崩 、缓存击穿)

黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 总时长 42:48:00 共175P 此文章包含第40p-第p45的内容 文章目录 缓存穿透解决方案缓存空对象布隆过滤 解决方案实现缓存穿透总结 缓存雪崩解决方案 缓存击穿解决方…

Elasticsearch 更新指定字段

Elasticsearch 更新指定字段 准备条件查询数据更新指定字段更新子级字段 准备条件 以下查询操作都基于索引crm_clue来操作&#xff0c;索引已经建过了&#xff0c;本文主要讲Elasticsearch更新指定字段语句&#xff0c;下面开始写更新语句执行更新啦&#xff01; 查询数据 查…

小阿轩yx-NoSQL 之 Redis 配置与优化

小阿轩yx-NoSQL 之 Redis 配置与优化 Redis 数据库介绍 是一个非关系型数据库 关系数据库与非关系型数据库 按照数据库结构划分的 关系型数据库 是一个结构化的数据库&#xff0c;创建在关系模型基础上&#xff0c;一般面向于记录借助集合代数等数学概念和方法处理数据库…

边缘计算网关:一种高效安全的工业物联网解决方案-天拓四方

在工业物联网&#xff08;IIoT&#xff09;领域&#xff0c;数据处理和实时响应的需求日益增长&#xff0c;尤其是在智能制造、远程监控和预测性维护等场景中。边缘计算网关作为一种前端数据处理和决策设备&#xff0c;正逐渐成为满足这些需求的理想解决方案。 在一个大型制造…

音频语言学习领域数据集现状、分类及评估

Audio Language Learning (Audio-Text Learning) 是一个新兴的研究领域&#xff0c;专注于处理、理解和描述声音。它的发展动力是机器学习技术的进步以及越来越多地将声音与其相应的文本描述相结合的数据集的可用性。 Audio Language Models (ALMs) 是这个领域的关键技术&#…

部署大语言模型并对话

在阿里云的https://developer.aliyun.com/adc/scenario/b105013328814fe995c0f091d708d67d 选择函数计算 设置服务器配置 复制公网地址 这个地址不能直接 在返回应用&#xff0c;创建应用LLM 对话页面 Open WebUI 点击下面的创建应用 部署完成后访问域名 打开访问地址

欧科云链研究院:坎昆升级后,Layer2变得更好了吗?

本文由欧科云链研究院OKG Research联合PANews出品&#xff1a;以数据为导向&#xff0c;洞察真实的链上世界。 作者&#xff5c;Jason Jiang, OKG Research 坎昆升级后&#xff0c;以太坊L2的交易费用降低明显且吞吐量有所提升&#xff0c;但整体生态并没有迎来想象中的繁荣景…

0基础学会在亚马逊云科技AWS上利用SageMaker、PEFT和LoRA高效微调AI大语言模型(含具体教程和代码)

项目简介&#xff1a; 小李哥今天将继续介绍亚马逊云科技AWS云计算平台上的前沿前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS上的AI软甲开发最佳实践&#xff0c;并应用到自己的日常工作里。本次介绍的是如何在Amazon SageMaker上…

【漏洞复现】Splunk Enterprise for Windows 任意文件读取漏洞 CVE-2024-36991

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 Splunk Enterprise 是一款强大的机器数据管理和分析平台&#xff0c;广泛应用于企业中&#xff0c;用于实…

应用最优化方法及MATLAB实现——第3章代码实现

一、概述 在阅读最优方法及MATLAB实现后&#xff0c;想着将书中提供的代码自己手敲一遍&#xff0c;来提高自己对书中内容理解程度&#xff0c;巩固一下。 这部分内容主要针对第3章的内容&#xff0c;将其所有代码实现均手敲一遍&#xff0c;中间部分代码自己根据其公式有些许的…

百度安全大模型智能体实践入选信通院“安全守卫者计划”优秀案例

7月3日&#xff0c;由全球数字经济大会组委会主办&#xff0c;中国信息通信研究院&#xff08;以下简称中国信通院&#xff09;与中国通信标准化协会联合承办的2024全球数字经济大会“云和软件安全论坛暨第二届SecGo云和软件安全大会”在北京召开。本届论坛聚焦云和软件安全最新…

从基础到进阶:无线局域网技术解析

在局域网刚刚问世后的一段时间内&#xff0c;无线局域网的发展比较缓慢&#xff0c;其原因是价格贵、数据传输速率低、安全性较差。但自20世纪80年代末以来&#xff0c;由于人们工作和生活节奏的加快&#xff0c;以及移动通信技术的飞速发展&#xff0c;无线局域网逐步进入市场…

今年2024,而那一年是1984

那一年&#xff0c;是1984 对于经历了改革开放洪流的国人来说&#xff0c;1984年似乎没有什么特别。 可是这一年&#xff0c;又确确实实非同寻常&#xff0c;许多后来的巨大变迁&#xff0c;在这一年埋下了伏笔…… 文学创作: 余华、莫言等作家在这一年迎来了自己的创作高峰…

学习通er图和项目思路

ER图 项目构思&#xff1a; 用户功能&#xff1a; 主要功能逻辑&#xff1a;

Web3知识图谱,一篇读完

这张图展示了区块链生态系统的架构和主要组件。以下是对图中内容的概括总结&#xff1a; 基础层&#xff1a; 底层基础设施&#xff1a;包括光纤网络、P2P网络、非对称加密、哈希算法、默克尔树和随机数生成。共识机制&#xff1a; PoW&#xff08;工作量证明&#xff09;: 比特…

Elasticsearch:介绍 retrievers - 搜索一切事物

作者&#xff1a;来自 Elastic Jeff Vestal, Jack Conradson 在 8.14 中&#xff0c;Elastic 在 Elasticsearch 中引入了一项名为 “retrievers - 检索器” 的新搜索功能。继续阅读以了解它们的简单性和效率&#xff0c;以及它们如何增强你的搜索操作。 检索器是 Elasticsearc…

MyBatis框架学习笔记(三):MyBatis重要文件详解:配置文件与映射文件

1 mybatis-config.xml-配置文件详解 1.1 说明 &#xff08;1&#xff09;mybatis 的核心配置文件(mybatis-config.xml)&#xff0c;比如配置 jdbc 连接信息&#xff0c;注册 mapper 等等都是在这个文件中进行配置,我们需要对这个配置文件有详细的了解 &#xff08;2&#x…

如何做好漏洞扫描工作提高网络安全

在数字化浪潮席卷全球的今天&#xff0c;企业数字化转型已成为提升竞争力、实现可持续发展的关键路径。然而&#xff0c;这一转型过程并非坦途&#xff0c;其中网络安全问题如同暗礁般潜伏&#xff0c;稍有不慎便可能引发数据泄露、服务中断乃至品牌信誉受损等严重后果。因此&a…