首页 > 其他分享 >springboot 解决跨域问题

springboot 解决跨域问题

时间:2023-06-16 11:47:55浏览次数:45  
标签:浏览器 请求 同源 cors 解决 跨域 public springboot

什么是跨域

指从一个域名网页去请求另一域名页面的资源,比如 baidu.com 请求 google.com 中的资源,但是这种情况是不允许的,因为由浏览器的同源策略,使浏览器对js增加安全限制,即就是阻止不同域下的js进行交互。判断域是否相同是通过判断协议、域名、端口中有任何一个不同,则为不同的域。

什么是同源策略

1、同源策略(Same origin policy)是一种约定,是由Netscape提出的一个著名的安全策略,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

2、举例:

当一个浏览器的两个tab页中分别打开来 百度谷歌的页面

当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,

即检查是否同源,只有和百度同源的脚本才会被执行。

如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

3、同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。

4、同源指:协议、域名、端口都相同。

5、同源策略是基于安全方面的考虑提出的,这个策略本身没有问题,但是在实际开发中,由于其他原因经常有跨域的需求,所以需要跨域的解决方案。

传统的跨域解决凡是 jsonP,jsonP 虽然能解决跨域问题但缺点就是只支持 get 请求。所以有了 cors 来解决 不同请求下跨域资源共享问题。

6、CORS 是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,它是w3c标准,是一份浏览器技术的规范,提供了web服务从不同网域js交互方法,以避开浏览器的同源策略。

springboot 实现 cors

需要创建两个springboot 项目,一个为 provider提供服务的项目,一个为consumer消费服务的项目。

先看没有 cors 的情况

无 cors 情况

提供服务(provider)

1、创建提供服务的项目,添加依赖(provider)

因为需要模拟网页,所以需要 web 依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2、配置端口

server.port=8080

3、提供接口

@RestController
public class HelloController {
    @GetMapping("/h")
    public String hello(){
        return "hello cros";
    }
    @PutMapping ("/h1")
    public String he(){
        return "hello put cros";
    }
}

消费服务(consumer)

1、添加依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2、配置端口

server.port=8081

3、页面准备

在resources/static下创建 index.html 文件,用于发送简单的 ajax 请求

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<input type="button" onclick="getData()" value="get"><br>
<input type="button" onclick="putData()" value="put"><br>
<script>
    function getData() {
        $.get("http://localhost:8080/h",function (msg){
            alert(msg);
        })
    }
    function putData() {
        $.ajax({
            url:"http://localhost:8080/h1",
            type:"put",
            success:function (msg) {
                alert(msg);
            }
        })
    }
</script>
</body>
</html>

启动两个项目,通过消费服务的页面定义的按钮,点击后会发现浏览器控制台输出如下:

可以看出由于同源策略的限制,请求无法获取资源。

而当使用了 cors 可以在前端代码不做任何修改下,实现跨越。

有 cors 情况

只需在 服务提供者(provider)中进行配置即可

方式一:@CrossOrigin()

在提供的接口中添加 @CrossOrigin() 注解,该注解添加类或方法上都可。

@RestController
@CrossOrigin(value = "http://localhost:8081",maxAge = 8000)
public class HelloController {
    @GetMapping("/h")
    public String hello(){
        return "hello cros";
    }
    @PutMapping ("/h1")
    public String he(){
        return "hello put cros";
    }
}

通过注解的 value 属性,来设置请求的地址。maxAge:设置相应时间

重启项目,再次访问就正常访问了。

上述实现缺点就是,需要手动添加该组注解,如果多个类,多个方法,也得手动添加多个该注解

方式二:WebMvcConfigurer 全局配置

在 springboot 中通过全局配置来进行配置 cors。

全局配置需要在 springmvc 的配置类中重写 addCorsMappings方法即可

@Configuration
public class MyWebMvcConfiguar implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")//允许哪些接口
                .allowedMethods("*")
                .allowedOrigins("http://localhost:8081");
    }
}

/** :表示该应用的所有方法都会处理跨域请求,

allowedMethods:表示允许通过的请求方法

allowedOrigins:表示允许请求的地址

这样配置后就不必在每个类或方法上添单独配置跨域了。

方式三:CorsFilter

通过域过滤器,来进行跨域配置

@Configuration
public class MyWebMvcConfiguar implements WebMvcConfigurer {
    @Bean
    CorsFilter corsFilter(){
        //获取UrlBasedCorsConfigurationSource
        //其使用URL路径模式为请求选择CorsConfiguration。模式匹配可以通过PathMatcher或预先解析的PathPatterns来完成
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        //获取CorsConfiguration对象
        CorsConfiguration cfg = new CorsConfiguration();
        //设置cors
        cfg.addAllowedMethod("*");
        cfg.addAllowedOrigin("http://localhost:8081");
        //将设置cors 注册到CorsConfiguration中
        source.registerCorsConfiguration("/**", cfg);//pattern:配置哪些接口可以请求,config:跨域配置
        return new CorsFilter(source);
    }
}

cors存在的问题

虽然解决跨域请求问题使用户体验提高了,但是也有潜在的威胁,常见的是 CSRF,跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

例如:假如一家银行用以运行转账操作的URL地址如下:http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName

那么,一个恶意攻击者可以在另一个网站上放置如下代码:

如果有账户名为Alice的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失1000资金。

这种恶意的网址可以有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险

所以,浏览器在实际操作中,会对请求进行分类,分为简单请求,预先请求,带凭证的请求等,

预先请求会首先发送一个 options 探测请求,和浏览器进行协调请求,默认下跨域请求是不需凭证的,但可通过服务端配置要求客户端提供凭证,这样可以防止攻击。

或者添加校验token也可避免

标签:浏览器,请求,同源,cors,解决,跨域,public,springboot
From: https://www.cnblogs.com/xiarongblogs/p/17485166.html

相关文章

  • springboot整合redis
    1、添加依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>2、配置redis通过spring.redis.xxx来配置redis的信息spring.redis.hos......
  • springboot整合持久层
    springboot整合持久层1、整合mybatis这里以多数据源为例第一步创建springboot时,选上mybatis依赖在添加数据库驱动依赖:<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23<......
  • springboot整合mongodb
    springboot整合mongodb整合mongodb其实与整合redis相差不大1、依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency&......
  • git 解决 both modified 冲突
     >解决此冲突分为两种需求:1.查看冲突,选择需要保留的修改,解决冲突并提交到服务器2.撤销自己本地的修改,并且不提交>注释:需求1比较普遍,解决冲突后直接提交就好了,此处不详说,重点讲需求2以需求2为目的,提供以下解决方案,操作步骤如下:     1.gitstatus查看状态......
  • pycharm无法找到anaconda的环境【通过.conda/environments.txt配置解决】
    Windows10系统,Pycharm2022.3.2(ProfessionalEdition)Useexistingenvironment候选列表没有目标环境候选项,例如:找不到torchgpu环境,则在C盘->用户名->.conda/environments.txt追加D:\anaconda3\envs\torchgpu即可。 ......
  • 谷歌账户被封如何解决?
    被禁用英文原文:   Itlookslikethisaccountwasassociatedwithmultipleotheraccounts,orcreatedbyaprogram,andusedtoviolateGoogle’spolicies.Learnmore   Ifyouthinkyouraccountwasdisabledbymistake,requestareviewofthisdecision......
  • springboot 中使用 redis 处理接口的幂等性
    什么是接口幂等性?数学中:在一次元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同;在二次元运算为幂等时,自己重复运算的结果等于它自己的元素。计算机学中:幂等指多次操作产生的影响只会跟一次执行的结果相同,通俗的说:某个行为重复的执行,最终获取的结果是相同的,不会因......
  • 解决log4cxx退出时的异常
    解决log4cxx退出时的异常(金庆的专栏)如果使用log4cxx的FileWatchdog线程来监视日志配置文件进行动态配置,就可能碰到程序退出时产生的异常。程序退出时清理工作耗时很长时,该异常很容易出现。原因是main()之后FileWatchdog线程试图checkAndConfigure()检......
  • SpringBoot快速整合RabbitMq小案例
    对于一个直接创建的springBoot项目工程来说,可以按照以下步骤使用rabbitmq添加依赖:添加rabbitMQ的依赖。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>配置连接:在配置文件中配置虚拟主......
  • ros melodic安装,rosdep init失败解决方法
    1.背景:前段时间手贱把之前安装好的ros环境给删了,这两天刚好需要用,遇到了点之前踩过的坑,主要是众所周知的rosdepinit失败,这里记录一下。2.系统:Ubuntu18.043.网络环境:有魔法3.需求:安装rosmelodic版本4.安装步骤:a.基本流程都可以按照官方的进行,贴上链接:http://wiki.ro......