赞
踩
前端代码要做微前端,我们代码适配了的别人的基座,这个时候所有请求都跨域了
前端请求跨域,具体显现就不描述了,跨域出现的现象一大把
并且cloud的gateway服务没有配置跨域操作,但是gateway后面的微服务配置了跨域,这样就需要gateway不仅要配置允许跨域,还要屏蔽掉后面微服务的跨域配置(这个后面讲为何)
cloud配置跨域,这个简单,网上有很多方法,我记录下对于我来说验证通过的一种方法,直接yaml里面加上如下配置。。
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOriginPatterns: "*"
allowedMethods: "*"
allowed-headers: "*"
allowCredentials: true
好了,上面解决了配置跨域问题,紧接着出现一个新的问题,刚才说的后端微服务已经配置了跨域,这就导致前端收到请求的时候,access-control-allow-origin: http://y.jd.com,*
或者证书是两个ture。
要么所有后端微服务都去掉跨域配置,要么找到解决方式,将后端服务配置的跨域给替换掉。
其实我是打算所有微服务改造,但是有个大神建议我在gateway拦截器里面搞事情,处理掉response里面的跨域配置。
虽然我内心是拒绝的,但是为了成为一个有追求的coder,我决定尝试一下
其实gateway已经有一个resquest的过滤器了,现在要操作response,尝试各种方式,最终方案如下:
import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; import org.springframework.beans.factory.InitializingBean; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponseDecorator; 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 static org.springframework.http.HttpHeaders.*; @Component public class ResponseFilter implements GlobalFilter, Ordered, InitializingBean { protected Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpResponse originalResponse = exchange.getResponse(); DataBufferFactory bufferFactory = originalResponse.bufferFactory(); ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) { @Override public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) { try { HttpHeaders headers = originalResponse.getHeaders(); String requestUrl = exchange.getRequest().getURI().getPath(); List<String> origin = exchange.getRequest().getHeaders().get(ORIGIN); if(origin!=null && origin.size()>0){ List<String> origins = new ArrayList<>(); origins.add(origin.get(0)); //Access-Control-Allow-Origin回填,覆盖 headers.put(ACCESS_CONTROL_ALLOW_ORIGIN,origins); } //Access-Control-Allow-Credentials回填,覆盖 List<String> credentials = new ArrayList<>(); credentials.add("true"); headers.put(ACCESS_CONTROL_ALLOW_CREDENTIALS, credentials); } catch (Exception e){ logger.error("++++++++++++++++++++++++=log headers error", e); } return super.writeWith(body); } }; //这里别忘了build方法的response方法回填 return chain.filter(exchange.mutate().response(decoratedResponse).build()); } @Override public void afterPropertiesSet() throws Exception { logger.info("ResponseBodyFilter: [{}]"); } @Override public int getOrder() { //response的fileter一定要小于-1,具体原因忘了。 return -2; } }
这样就覆盖掉了gateway后面微服务的跨域配置。瞬间感觉自己萌萌哒!
本来以为事情就结束了,换了一个环境部署以后,发现不生效。依然跨域,我真是fffffffffffuck。
在排查这个问题之前,发现options请求是403,post是跨域,我就按照跨域问题排查:
尝试修改我的gateway配置,以为是gateway的错误,改了好多版本都不生效
然后打印日志,发现都没有进入gateway,我才想着去上游看看
没办法,从头开始定位问题,从网管开始,发现网管日志报错,重点注意报错 rbac_access_denied_matched_policy[none]
[2022-08-03T14:23:04.131Z] "OPTIONS /gw/usercenter/sys/query/user HTTP/1.1" 403 - rbac_access_denied_matched_policy[none] - "-" 0 19 0 - "ip " "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" "ba2a6902-6d98-9999-af12-85c3394e25bc" "mlops-test.jd.com" "-" - - ip2:8080 ip3:43921 - -
根据ip找了一下pod和svc,发现是istio网管 cluster-local-gateway的ip,也就是还没有我的gateway服务就被拦截,,
面向百度编程嘛,查查查,最后发现是istio的AuthorizationPolicy配置问题
添加上,瞬间就好了。
配一张简单手绘图:
1、OPTIONS请求失败,就会导致post请求报错跨域。
2、GW是个好东西,又是个经常扯我们蛋的工具,像上面的问题,如果没有GW,我就没有这些问题了。但是它有给我很大方便,例如认证,我只需要在GW里面做,后面服务就不用管了,当然认证被破解导致后面服务的危险是认证的问题,和GW无关
3、碰到问题,理清楚思路,从入口开始往下一步一步排查,例如istio的配置,我找了一圈,没有找到原因,才想着回头看istio网管日志的,如果早点看,可能早就解决了。
参考文档:
https://blog.csdn.net/tanjunchen/article/details/123303084
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。