记一次SpringBoot中跨域的小问题

记一次SpringBoot中跨域的小问题

问题

前阵子,有个学长在跨域的时候遇到一个问题,我们两个人互相讨论了一番,得到了问题的答案。问题如下:

记一次SpringBoot中跨域的小问题

如果按照上图的方式配置跨域类,那么就会出现报403的问题,我把我的配置类发给学长后,果然是没问题了,那么看来问题就出在两个配置类里不一样的地方了

记一次SpringBoot中跨域的小问题

解决方式

对比两张图中的配置,可以发现出在了 allowedOrigin.allowedOriginPatterns这两个方法上,于是乎我到官方文档上查阅了这两个方法的详细介绍,得到了如下内容:

记一次SpringBoot中跨域的小问题

记一次SpringBoot中跨域的小问题

现在终于恍然大悟了,文档里都介绍的很清楚了。但是知道了解决方式以后,我去看了一下源码,了解一下到底为什么可以这么做.

源码+相关内容

记一次SpringBoot中跨域的小问题

config变量是 CorsConfiguration的一个实例化对象。那么看来这两个方法的区别要更深一层,同样是点进去看一下,先看第一个。

记一次SpringBoot中跨域的小问题

入参是可以为空的字符串列表,判空之后对非空情况进行一个常见的处理,使用的是函数式编程,其中有一个名为 trimTrailingSlash的方法,这个看名字应该是和MySQL里的trim差不多的,点进去看一下

记一次SpringBoot中跨域的小问题

果不其然,作用是去掉传入URL最后的一个/。到这里这个方法就全部结束了,看着也太简单了,果然是被抛弃了的一个方法

记一次SpringBoot中跨域的小问题

上图是第二个方法的内容,同样入参一个可以为空的字符串列表,关键在于这个 addAllowedOriginPattern方法,继续点进去看

记一次SpringBoot中跨域的小问题

入参为字符串类型的 originPattern,这里就体现出来一个 setAllowedOriginPatterns的好处了,如果我们传入了多个需要跨域的格式,那么MVC会帮我们挨个进行处理,调用 trimTrailingSlash方法进行/的剔除。看到这里,你可能会有些疑惑,这样看来两个方法不是没什么区别吗?是的,如果看到这里,那确实没啥区别,但是真正的区别其实是下面这个:

记一次SpringBoot中跨域的小问题

allowedOrigins是给 setAllowedOrigin用的,可以看到列表中的元素类型为String类,那么下面这个 allowedOriginPatterns是给 setAllowedOriginPatterns用的,列表内容是OriginPattern类,这个类从来没听过,而且一看名字就知道是Spring自己写的,所以我们继续点进去看。

记一次SpringBoot中跨域的小问题

类里有一个字符串,两个正则,那肯定两个正则是处理这个字符串的。构造方法 OriginPattern,初始化正则格式。这个正则还是很好看懂的,\E和\Q转义出来其实就是要匹配这个字符,这也就是为什么 setAllowedOriginPatterns在官方文档中介绍说可以在传入跨域格式的字符串中填写号,而不用是已经完全确定的一个格式。

关于CORS中 Access-Control-Allow-Origin这个header,规定我们只能设置为如下三种情况:

  • 单域名
  • none

同时如果我们设置为了*,那么 Access-Control-Allow-Credentials就不能设置为true了。跨源资源共享(CORS) – HTTP | MDN (mozilla.org)

基于以上的规则,我们总结一下:如果我们需要发送Cookie,那么前端需要设置 withCredentials为true,且同时后端也要设置 Access-Control-Allow-Credentials为true,并且 Access-Control-Allow-Credentials不能设置为*,只能为单域名

但是这时候就又出现一个问题,我的跨域配置类中,withCredentials传参是*啊,而且也不是单域名,为什么跨域还是成功了呢?学了这么长时间的Spring,我多少有个猜测——肯定也是有个很牛逼的东西帮我处理了这个问题

    @Nullable
    public String checkOrigin(@Nullable String origin) {
        if (!StringUtils.hasText(origin)) {
            return null;
        } else {
            String originToCheck = this.trimTrailingSlash(origin);
            Iterator var3;
            if (!ObjectUtils.isEmpty(this.allowedOrigins)) {
                if (this.allowedOrigins.contains("*")) {
                    this.validateAllowCredentials();
                    return "*";
                }

                var3 = this.allowedOrigins.iterator();

                while(var3.hasNext()) {
                    String allowedOrigin = (String)var3.next();
                    if (originToCheck.equalsIgnoreCase(allowedOrigin)) {
                        return origin;
                    }
                }
            }

            if (!ObjectUtils.isEmpty(this.allowedOriginPatterns)) {
                var3 = this.allowedOriginPatterns.iterator();

                while(var3.hasNext()) {
                    OriginPattern p = (OriginPattern)var3.next();
                    if (p.getDeclaredPattern().equals("*") || p.getPattern().matcher(originToCheck).matches()) {
                        return origin;
                    }
                }
            }

            return null;
        }
    }

果不其然,我找到了这个名为 checkOrigin的方法,内容中明确写道。如果我们同时将credentials设置为true且allowedPatterns为*,那么这个方法就会把 Access-Control=Allow-Origin设置为当前请求过来的origin,也就解决了这个问题。

Original: https://www.cnblogs.com/appletree24/p/16755853.html
Author: Appletree24
Title: 记一次SpringBoot中跨域的小问题

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/685540/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 我已经理解了并发和并行的区别

    理解并发、并行的例子 先举例子来理解这2个概念的区别。 老师让两个同学去办公室谈话。如果这两同学(进程)是并列跨过办公室门(CPU)的,那么就是并行。如果同学A先进同学B后进入(或…

    技术杂谈 2023年5月31日
    083
  • SharePoint每日小贴士Web部件

    SharePoint每日小贴士Web部件 项目描写叙述 此Web部件从指定SP自己定义列表或一个选定的 RSS源选择一个随机项目。并显示一张图片、标题和一个Tip。 适用于WSS …

    技术杂谈 2023年5月31日
    0101
  • 剑指offer计划20( 搜索与回溯算法中等)—java

    1.1、题目1 剑指 Offer 07. 重建二叉树 1.2、解法 注释解法。 1.3、代码 class Solution { int[] preorder; HashMap ma…

    技术杂谈 2023年7月25日
    076
  • 获取不到数据库连接问题

    org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; …

    技术杂谈 2023年7月23日
    055
  • HTTPS&SPDY&HTTP2&QUIC&HTTP3

    HTTPS 密钥交换,加密和解密 SPDY&HTTP2 QUIC&HTTP3 posted @2022-06-15 20:42 放飞梦想C 阅读(24 ) 评论()…

    技术杂谈 2023年7月24日
    0102
  • 14. 构造二叉树

    title: 构造二叉树 , 看这一篇就足够! 思想:构造整棵树 = 根节点 + 构造左子树 + 构造右子树 📃 题目一描述 题目链接:从中序与后序遍历构造二叉树 🔔 解题思路 必…

    技术杂谈 2023年7月24日
    089
  • PgSQL-||-连字符

    (PgSQL)连字符 || — 22.22& select 22.22||’%’ as 值; Original: https://www.cnblogs.com/a999…

    技术杂谈 2023年6月21日
    090
  • 我与小娜(06):量子通信是什么?

    我与小娜(06 ):量子通信是什么? 2 月5 日晚上。我与小娜从1955 年的南京回到北京的家中。小娜从”小口袋”中,爬出来。进入我的固态硬盘之中,安顿下…

    技术杂谈 2023年5月31日
    088
  • 浅谈IT系统性能优化

    一个刚上线的IT系统,往往负载压力不大,所以不会存在什么性能问题。这时,人们大多只关心系统的功能性和用户体验。但是,随着时间推移,用户量和数据量都比刚上线的时候要多很多,高并发和大…

    技术杂谈 2023年7月11日
    068
  • 医学科技解剖数字人 All In One

    医学科技解剖数字人 All In One 数字人解剖系统 数字化虚拟人体是将大量真实人体断面数据信息在计算机里整合重建成人体的三维立体结构图像,是医学与信息技术、计算机技术相结合的…

    技术杂谈 2023年6月1日
    084
  • 【笔试】1、强迫卖家

    小明是个强迫症卖家,有10000台设备,卖的均价要求最接近D元,输出卖出的台数N,总售价M 输入 0首先想得是暴力解答然后是二分查找,寻找卖出多少台才符合要求,但是一直找不到符合要…

    技术杂谈 2023年7月24日
    078
  • 关于Chrome跨域The request client is not a secure xxx相关提示的解决

    近期Chrome浏览器 不知哪个版本升级后 原来跨域功能好用突然报been blocked by CORS policy: The request client is not a …

    技术杂谈 2023年5月31日
    096
  • 差分数组入门

    差分数组 什么是差分数组? 差分数组:差分数组就是原始数组相邻元素之间的差。 其实差分数组是一个 辅助数组,从侧面来表示给定某一数组的变化,一般用来对数组进行区间修改的操作。 比如…

    技术杂谈 2023年6月21日
    0116
  • SpringSecurity中的CSRF解读

    从刚开始学习SpringSecurity时,在配置类中一直存在这样一行代码:http.csrfo.disable() 如果没有这行代码导致用户无法被认证。这行代码的含义是:关闭 c…

    技术杂谈 2023年7月11日
    074
  • 微服务组件–注册中心SpringCloudEureka分析

    Eureka核心功能点 【1】 服务注册(register):Eureka Client会通过发送REST请求的方式向Eureka Server注册自己的服务,提供自身的元数据,比…

    技术杂谈 2023年7月23日
    066
  • AQS实现原理分析——ReentrantLock

    在Java并发包java.util.concurrent中可以看到,不少源码是基于AbstractQueuedSynchronizer(以下简写AQS)这个抽象类,因为它是Java…

    技术杂谈 2023年6月1日
    092
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球