SpringBoot(十五)单个以及多个跨域的配置方法
同源策略是浏览器的一个安全限制,要求域名、协议、端口相同,如果不同则没办法进行数据交互。
而跨域配置,则是为了解除这方面的限制。
前后端分离的情况下,因为需要分开部署,后台开发基本都需要进行跨域配置了。
(当然,这也可以在 nginx 上处理,这里就不展开讨论了)
spring 提供的跨域拦截器是 CorsFilter,与 CorsFilter 强关联的类是 UrlBasedCorsConfigurationSource。
跨域配置实体类
参数介绍可以看代码注释
* 跨域配置一览:
* <p>
* Access-Control-Allow-Origin: 允许访问的域名
* Access-Control-Allow-Methods: 允许访问的请求方式
* Access-Control-Allow-Headers: 允许使用的Header
* Access-Control-Allow-Credentials: 是否允许用户发送、处理Cookie
* Access-Control-Max-Age: 预检有效期,单位为秒。有效期内,不需要重复发送预检请求
* Access-Control-Expose-Headers: Header白名单,不设置的话,客户端读不到header的内容
*
* @author Mr.css
* @date 2022-03-09 16:55
*/
public class CrossDomain implements Serializable {
private static final long serialVersionUID = -3682297338044962128L;
/**
* 路径,Controller提供的接口
*/
@Length(max = 64)
@Schema(description = "路径")
private String antPath;
/**
* 允许访问的IP
*/
@Length(max = 64)
@Schema(description = "允许访问的IP")
private String allowedOrigin;
/**
* 开放请求头
*/
@Length(max = 64)
@Schema(description = "允许的请求头")
private String allowedHeader;
/**
* 开放请求方式
*/
@Length(max = 32)
@Schema(description = "允许的请求方式")
private String allowedMethod;
/**
* 白名单Header
*/
@Length(max = 64)
@Schema(description = "白名单Header")
private String exposedHeader;
/**
* 预检请求有效期
*/
@Schema(description = "预检请求有效期")
private Integer maxAge;
/**
* 允许携带凭证
*/
@Schema(description = "允许携带凭证")
private Boolean allowCredentials; // 省略getter/setter
}
Yml配置
YML配置方式,与实体类字段对应
boot-cross-domain:
config:
allowed-origin: 'http://localhost:8080'
ant-path: '/**'
allowed-header: '*'
allowed-method: '*'
allow-credentials: true
默认配置方式(单个跨域)
如果客户端不多,默认的配置就已经很好用了。
import cn.seaboot.common.core.CommonUtils;
import cn.seaboot.common.lang.Warning;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter; /**
* 跨域配置
*
* @author Mr.css
* @date 2020-07-08 09:04
**/
@Configuration
@ConfigurationProperties(prefix = "boot-cross-domain")
public class CrossDomainStarter {
private Logger logger = LoggerFactory.getLogger(CrossDomainStarter.class); private CrossDomain config; public CrossDomain getConfig() {
return config;
} public void setConfig(CrossDomain config) {
this.config = config;
} @Bean
@SuppressWarnings(Warning.UNCHECKED)
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
logger.info("【Configuration】Cross domain setting: start...");
CorsConfiguration corsConfiguration = new CorsConfiguration();
String origin = config.getAllowedOrigin();
if (origin.endsWith("/") || origin.endsWith("\\")) {
origin = origin.substring(0, origin.length() - 2);
}
corsConfiguration.addAllowedOrigin(origin); //AllowedHeader
String allowHeader = config.getAllowedHeader();
if (CommonUtils.isNotEmpty(allowHeader)) {
for (String header : allowHeader.split(",")) {
corsConfiguration.addAllowedHeader(header);
}
} //AllowedMethod
String allowedMethod = config.getAllowedMethod();
if (CommonUtils.isNotEmpty(allowedMethod)) {
for (String method : allowedMethod.split(",")) {
corsConfiguration.addAllowedMethod(method);
}
}//AllowedHeader
String exposedHeader = config.getExposedHeader();
if (CommonUtils.isNotEmpty(exposedHeader)) {
for (String header : exposedHeader.split(",")) {
corsConfiguration.addExposedHeader(header);
}
} //MaxAge
if (config.getMaxAge() != null) {
corsConfiguration.setMaxAge(config.getMaxAge().longValue());
} //AllowCredentials
if (config.getAllowCredentials() != null) {
corsConfiguration.setAllowCredentials(config.getAllowCredentials());
}
logger.info("Cross domain using config: {}", config);
source.registerCorsConfiguration(config.getAntPath(), corsConfiguration);
logger.info("【Configuration】Cross domain setting: finish");
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new CorsFilter(source));
filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return filterRegistrationBean;
}
}
配置多个跨域
* Access-Control-Allow-Origin: 允许访问的域名
* Access-Control-Allow-Methods: 允许访问的请求方式
* Access-Control-Allow-Headers: 允许使用的Header
* Access-Control-Allow-Credentials: 是否允许用户发送、处理Cookie
这些参数本身就可以配置多个,用逗号分隔即可。
增加更多的跨域配置
逗号拼接的方式,决定了功能上限,如果有很多个客户端,配置起来就会很乱,比如说,我有10个客户端要配置怎么办?
这种场景下,通常会选择直接使用通配符 *,放开跨域拦截,通过业务控制,或者通过鉴权系统控制。
虽说如此,强行实现一波,应当如何?
直接看源码,上面我们用到了 UrlBasedCorsConfigurationSource,
UrlBasedCorsConfigurationSource 的父类是 CorsConfigurationSource,
这个类,相当于Dao,参数是 request,根据 request 的内容查找对应的跨域配置。
我们可以自己实现一个 CorsConfigurationSource。
代码贴出来显得文章篇幅太大,而且代码功能单一,就是配置查询,这次就简单地说明一下,下面提供了伪代码作为参考。
@Override
@Nullable
public CorsConfiguration getCorsConfiguration(@NotNull HttpServletRequest request) {
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
// 获取客户端域名
String origin = request.getHeader(HttpHeaders.ORIGIN);
// TODO: 根据客户端的域名,查找CorsConfiguration配置
return null;
}
SpringBoot(十五)单个以及多个跨域的配置方法的更多相关文章
- springboot(十八):CORS方式实现跨域
资料 https://www.cnblogs.com/toutou/p/9843588.html
- SpringBoot 优雅配置跨域多种方式及Spring Security跨域访问配置的坑
前言 最近在做项目的时候,基于前后端分离的权限管理系统,后台使用 Spring Security 作为权限控制管理, 然后在前端接口访问时候涉及到跨域,但我怎么配置跨域也没有生效,这里有一个坑,在使用 ...
- vue+springboot前后端分离实现单点登录跨域问题处理
最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登 ...
- Springboot实现filter拦截token验证和跨域
背景 web验证授权合法的一般分为下面几种 使用session作为验证合法用户访问的验证方式 使用自己实现的token 使用OCA标准 在使用API接口授权验证时,token是自定义的方式实现起来不需 ...
- Web API(五):Web API跨域问题
一.什么是跨域问题 跨域:指的是浏览器不能执行其他网站的脚本.是由浏览器的同源策略造成的,是浏览器施加的安全限制.(服务端可以正常接收浏览器发生的请求,也可以正常返回,但是由于浏览器的安全策略,浏览器 ...
- 两种解决springboot 跨域问题的方法示例
两种解决springboot 跨域问题的方法示例,哪种方法看情况而定,自己选择.社会Boolean哥,人狠话不多,直接上代码. 第一种实现方式: 此种方式做全局配置,用起来更方便,但是无法 ...
- 浅谈配置chrome浏览器允许跨域操作的方法
浅谈配置chrome浏览器允许跨域操作的方法 一:(Lying人生感悟.可忽略) 最近有一天,对着镜子,发现满脸疲惫.脸色蜡黄.头发蓬松.眼神空洞,于是痛诉着说生活的不如意,工作没激情,工资不高,一个 ...
- Nginx反向代理、CORS、JSONP等跨域请求解决方法总结
由于 Javascript 同源策略的存在使得一个源中加载来自其它源中资源的行为受到了限制.即会出现跨域请求禁止. 通俗一点说就是如果存在协议.域名.端口或者子域名不同服务端,或一者为IP地址,一者为 ...
- spring mvc \ spring boot 允许跨域请求 配置类
用@Component 注释下,随便放个地方就可以了 package com.chinaws.wsarchivesserver.core.config; import org.springframew ...
- Web Api跨域访问配置及调用示例
1.Web Api跨域访问配置. 在Web.config中的system.webServer内添加以下代码: <httpProtocol> <customHeaders> &l ...
随机推荐
- 如何调用别人的接口(包含get请求post请求)
对于如何调用第三方接口还是有些模糊,所以记录一下,上代码 package com.zhang.miaodou; import java.io.BufferedReader; import java.i ...
- java语言——跨平台原理,jre,jdk
day1 Java是一种混合的编译运行方式:编译+解释(虚拟机) java的跨平台:在虚拟机中运行(jvm) jdk:jvm,核心类库,开发工具(开发环境) jre:Java的运行环境
- sqlserver 循环插入脚本
Declare @i int = 0 -- 说明需要插入的列值 WHILE @i< 1000000 BEGIN -- 需要写入数据的值 insert into ... set @i = @i + ...
- codeforce D. Concatenated Multiples
http://codeforces.com/contest/1029/problem/D 看C题的第一眼就觉得自己一定能做出来,结果就兴致勃勃地做了一天,最后做出来了.但看到这道题时,第一感觉就是&q ...
- PHP面向对象(三)
对象的引用 代码如下: <?php//类的定义以关键字class开始,类的命名通常以每个单词第一个字母大写 class NbaPlayer{ public $name = & ...
- 获取select的选中的值
var select = document.getElementById("sec")//获取元素 var idx = select.selectedIndex;//获取当前选中的 ...
- ASP.NET Core http请求内容过大, IIS服务器 返回 Request Too Long 解决方案
1.修改web.config文件内容如下: <?xml version="1.0" encoding="utf-8"?> <configura ...
- ChatGPT回答的关于maxscript + python
- MAC怎么快速截图
1.截取全屏 按住[command][shift][3]这三个键即可截取全屏. 编辑 2.截取某区域 按住[command][shift][4]. 编辑 3.截图完成 在电脑桌面能找到截图 ...
- Android自动化用例编写
java -jar appcrawler.jar<路径> --demo java -jar appcrawler.jar<路径> \ -c example.yml \ --c ...