首页 > 其他分享 >微服务跨域配置

微服务跨域配置

时间:2022-12-07 14:04:34浏览次数:41  
标签:Control 服务 跨域 配置 springframework kv org import

有时候,我们需要对所有微服务跨域请求进行处理.

跨域的说明:

哪些场景是跨域:不同的系统进行AJAX的请求的时候属于跨域的。 跨域的请求一般是不被允许的。

1.www.jd.com---->www.taobao.com 跨域

2.localhost:8001 —>localhost:8002 跨域

3.www.jd.com:80—>www.jd.com:81 跨域

4.https —>http 跨域。

域名相同,端口相同,协议相同 就不是跨域。

  1. 解决跨域的问题的解决方案:
  • CORS的协议 (高版本的浏览器至少 IE10 google)
  • 在服务端进行注解配置(相当配置了CORS的配置项)springmvc的注解 @CrossOrigin
  • 通过在网关(spring cloud gateway)进行统一的配置
  • 通过在网关(nginx里面进行配置CORS)
  1. JSONP的方式(了解) 利用JS的漏洞的实现跨域,而且只支持GET请求 不支持其他的请求。

解决方式涉及到图如下:

通过@CrossOrigin()注解实现 

微服务跨域配置_跨域

如果都需要跨域处理,该方式需要在每一个Controller类上配置。

另外我们一般在SpringCloudGateway网关配置

spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOriginPatterns: "*"
allowed-methods: "*"
allowed-headers: "*"
allow-credentials: true
exposedHeaders: "Content-Disposition,Content-Type,Cache-Control"

如果不想配置到yml也可以代码写在网关模块中

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

/**
* 跨域配置
*/
@Configuration
public class CorsConfig
{
/**
* 这里为支持的请求头,如果有自定义的header字段请自己添加
*/
private static final String ALLOWED_HEADERS = "X-Requested-With, Content-Type, Authorization, credential, X-XSRF-TOKEN, token, Admin-Token, App-Token";
private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD";
private static final String ALLOWED_ORIGIN = "*";
private static final String ALLOWED_EXPOSE = "*";
private static final String MAX_AGE = "18000L";

@Bean
public WebFilter corsFilter()
{
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (CorsUtils.isCorsRequest(request))
{
ServerHttpResponse response = ctx.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
headers.add("Access-Control-Max-Age", MAX_AGE);
headers.add("Access-Control-Allow-Credentials", "true");
if (request.getMethod() == HttpMethod.OPTIONS)
{
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(ctx);
};
}
}

前端页面通过不同域名或IP访问SpringCloud Gateway,那么,此时直连微服务和网关的跨域问题都解决了,是不是很完美?

No~ 问题来了,前端仍然会报错:“不允许有多个’Access-Control-Allow-Origin’ CORS头”。

问题:Vary 和 Access-Control-Allow-Origin 两个头重复了两次,其中浏览器对后者有唯一性限制!

解决方式之一:手动写一个 CorsResponseHeaderFilter 的 GlobalFilter 去修改Response中的头。

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {


private static final String ANY = "*";

@Override
public int getOrder() {
// 指定此过滤器位于NettyWriteResponseFilter之后
// 即待处理完响应体后接着处理响应头
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
}

@Override
@SuppressWarnings("serial")
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
exchange.getResponse().getHeaders().entrySet().stream()
.filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
.filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)
|| kv.getKey().equals(HttpHeaders.VARY)))
.forEach(kv ->
{
// Vary只需要去重即可
if(kv.getKey().equals(HttpHeaders.VARY))
kv.setValue(kv.getValue().stream().distinct().collect(Collectors.toList()));
else{
List<String> value = new ArrayList<>();
if(kv.getValue().contains(ANY)){ //如果包含*,则取*
value.add(ANY);
kv.setValue(value);
}else{
value.add(kv.getValue().get(0)); // 否则默认取第一个
kv.setValue(value);
}
}
});
}));
}
}

基于SpringCloudGateway网关配置完成。

 

标签:Control,服务,跨域,配置,springframework,kv,org,import
From: https://blog.51cto.com/u_15430445/5917746

相关文章

  • DataX源码分配三:配置加载
    【1】入口ConfigParser::parse   方法参数为命令行中指定的作业配置文件。 【2】配置保存方式datax使用Configuration类保存作业配置,保存方式简单粗暴。Config......
  • springmvc零配置项目开发流程
    最后更新日期:2022-12-071.概述本篇主要介绍使用springmvc零配置开发项目的过程。参考博客:《SpringMVC学习(五)——零配置实现SrpingMVC》博客内容简洁不全,其源码托......
  • 为什么Git远程仓库中要配置公钥?
    最近在使用阿里云效平台代码管理,首次使用新建仓库,使用SSH时需要配置公钥。之前也在GitHub、Gitee上配置过,每次都能正常使用,也没有思考过为什么要配置公钥。这次记录一下其......
  • centos在VMware的net配置与静态ip
    centos在VMware的net配置与静态ip关键字:vmware;CentOS7最小安装;NAT网络模式,静态IP本机操作,1.查看本机ip并记录,假如为192.168.194.2312.修改虚拟机网络配置3.保......
  • 【Ubuntu服务器】用户分配及sudo权限赋予
    SSH服务部署服务器刚刚部署Ubuntu环境,并不支持SSH访问服务器,所以需要先安装openssh-serversudoaptupdatesudoaptinstallopenssh-server安装完成后,SSH服务将被自......
  • 还在用Feign?推荐一款微服务间调用神器,跟SpringCloud绝配
     简介:大家好,我是枫哥,......
  • 配置redis遇到Could not resolve placeholder 'redis.maxIdle' in string value "${re
    这个错误是读取不到我们自己redis.properties文件,因为我们在配置数据库链接时已经配置过一次  “Spring容器是采用反射扫描的发现机制,通过标签的命名空间实例化实例,......
  • 服务器——切换cuda版本
    第一步:找到对应的​​.bashrc​​文件第二步:输入以下命令(该命令是切换到cuda10.2)exportPATH="/usr/local/cuda-10.2/bin:$PATH"exportLD_LIBRARY_PATH="/usr/local/cuda......
  • 【阿里云】服务部署
    服务部署https://www.bilibili.com/video/BV1kD4y1v7Fk/?spm_id_from=333.337.search-card.all.click&vd_source=d11276664e3a69665cdbcae735af16dc打包jarjar是类的归......
  • 各开发语言DNS缓存配置建议
    作者:翟贺龙一、背景在计算机领域,涉及性能优化动作时首先应被考虑的原则之一便是使用缓存,合理的数据缓存机制能够带来以下收益:1.缩短数据获取路径,热点数据就近缓存以便后......