小伙子把我坑了,改造网关filter,一直报跨域

2023-10-07 20:40

本文主要是介绍小伙子把我坑了,改造网关filter,一直报跨域,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

闲聊


1、项目研发负责人需要具备主动性

阿里招聘简历上,常常会带上一句话:具备owner意识。它的逻辑是怎样的呢?

【执行者角度】:我完成某项任务,I do it~

【owner角度】入手任务前,这个任务为了解决什么东西(核心价值)?它会引发你的思考,就是我有没有其他更好的方案去解决这个问题,其次是在实施前思考可行性、风险、扩展点。任务执行中,项目进度是不是在预期内,然后遇到什么问题需要主动寻求帮助。任务完成后,我们做这个项目它有没有发挥应有的价值,这时就要观察项目运转情况、业务情况,如果它是一个持续的过程,那么我们还要规划下一步内容。

我觉得这是我在当项目负载负责人的时候学习到的,我可以清晰观察到很多项目半死不活,就它只是服务于当下,可能上线后没有多少人去用它,它的价值完全没有发挥出来,just 一个摆设!

坚持做正确的事 --马斯克

马斯克在成功之前,大家都觉得他很疯狂,什么回收火箭,面对一次次失败,网上键盘侠噼里啪啦吐槽更猛;当他成功的时候,大家就会觉得很了不起。是啊,很多人只看花绽放的结果,但是花在成长过程,大家就会抗拒新的事物、新的尝试,并且加以诋毁。所以坚持做正确的事~

前言


我们最近项目终于开始接入统一登录了,其实sso统一登录项目也耽搁了很长一段时间,然后登录验证逻辑是交给权限中心去搞,也就是需要将之前网关登录鉴权filter改写,通过sdk的方式去注入到网关中。然后到了测试阶段,前端反馈有些接口一直报跨域,我就奇怪了,之前接口一直是好好的,然后网关也有配置跨域设置,咋会这样?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dH7F9wqN-1668392437436)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/037d094698724eaea777a1614e690be2~tplv-k3u1fbpfcp-watermark.image?)]

排查历程


1. 第一步:我观察网关跨域配置是否有问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YVcBm5Hv-1668392437437)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fc914c2620484c56a77ee938955f8691~tplv-k3u1fbpfcp-watermark.image?)]

没有问题,就是从网上copy下来的,哈哈哈

2. 思考:为什么会跨域?

小伙子提供了请求traceid给我,让我apm看看什么问题,好家伙,这网关给你改造然后你让我来看啥问题?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dm2cdr4e-1668392437438)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/320fa2f51690498ea4a51675806fb108~tplv-k3u1fbpfcp-watermark.image?)]

我们看到是能正常返回的,但是!是异常,验证已失效,请重新登录。

3. 第二步,检查网关跨域配置

为什么其他服务异常不会跨域,偏偏这登录鉴权异常就跨域?其实浏览器的跨域是因为同源机制导致,就是response需要加上特定header,Access-Control-Allow-Origin,Access-Control-Allow-Credentials;

那么我就去查网关是否有对异常进行处理:

@Slf4j
public class XxxFilter extends AbstractErrorWebExceptionHandler implements Ordered {@Overrideprotected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {return RouterFunctions.route(RequestPredicates.all(), request -> renderErrorJsonResponse(request, errorAttributes));}private Mono<ServerResponse> renderErrorJsonResponse(ServerRequest request, ErrorAttributes errorAttributes) {Map<String, Object> errorProperties = getErrorAttributes(request, ErrorAttributeOptions.of(ErrorAttributeOptions.Include.STACK_TRACE));// 获取合适的处理器对 response body 进行重写return rewriteFunctions.stream().orElseGet(() -> {Throwable throwable = errorAttributes.getError(request);return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(exceptionAdvice.handleException(throwable)));});}}

网关地方会重写异常的返回response,我idea本地测试一波,发现如果是服务异常,它不会走这里的,也就是只有出现Throwable异常抛出的时候才会被捕获。报错的接口却是走这个异常,问题慢慢揭开面纱~

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RJQ1sYN1-1668392437438)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4726d5ccf22040c5bda093fc25d3bb22~tplv-k3u1fbpfcp-watermark.image?)]

4. 第三步:查看接口的归属以及实现

我就去瞄了一眼,这个接口是哪个服务的,这是谁的部下,这么勇猛。好家伙,就是这期接入统一登录的接口,而且是白名单!

接下来我们就要进去看看对应的实现了,逻辑里头没有判断token是否过期啊,怎么肥事,老六。我就找啊找啊,发现居然还自带一个filter来检查访问的token是否有效的

在这里插入图片描述

这个就是gaetway web-flux的过滤器写法对吧,到这里还没有问题,我们再往下看

在这里插入图片描述

当我看到方法里头的实现的时候,我就觉得坏事了,因为我们网关filter是不会这么写的,直接抛出异常。

why?

业务系统我们习惯是throw new xxException对吧,这个没有错,因为业务系统有统一异常捕获。小伙子改造网关filter验证,也认为网关有异常捕获对吧。

其实呢,网关已经是最外层了,理论上不应该再抛出异常,应该直接返回响应的异常码还有信息。

到这里,我们就能解释清楚第三步,为啥这个接口走的是网关异常捕获,而不是直接返回了。 因为你在filter这里抛出异常,然后被网关异常handler捕获,重写了response

注意这里重写了response,导致header头的跨域头丢失了。

5. 第四步:在网关异常强行加上跨域头

注意这里是强行加上跨域头,你想想网关怎么可以有抛出异常呢?它只能有异常响应,不能直接抛出异常,它是两回事,前者是封装异常码、异常信息,后者是直接抛出异常,他们区别就是500,系统异常,那是万不得已才去全局捕获的,业务系统还能理解,但是网关的话人家捕获异常是为了防止万一,你偏偏要去通过抛出异常来处理,去走最后兜底方案。

在这里插入图片描述

到这里我们就解决了跨域问题

为什么直接改成输出异常码就不会有问题?


比如说跨域filter在这个鉴权filter后面,不就跨域头没了对吧,所以我们需要探索他们之间的先后顺序

首先CorsWebFilter 它是继承webfilter,正儿八经的网关拦截器,然后我们再看下鉴权filter,它也是继承webfilter,这下好玩了,我们只能通过order方法来决定他们的先后顺序。

其次还有另外做法,实现globalfilter,它虽然带上filter字样,其实是属于webhandler里头一个拦截器责任链。我们通过以前这篇文章介绍到网关构造,会先走webfilter,然后走webhandler,这个顺序不需要设定,一开始会走添加跨域头corsfilter,然后再进去webhandler,这样的好处也有一个,越往前它的粒度是越大的,我们这个鉴权的拦截器是针对网关某些白名单接口去限制的,范围会更小,应该滞后去处理。

这样的设计网关才符合漏斗形过滤机制,一层一层筛选以及处理!

  • 灰度方案-svc环境实现方案以及网关源码分析

在这里插入图片描述

回顾


导致的原因其实就是因为接入统一登录的时候,有些权限接口是白名单,通过网关filter来鉴权,但是呢,里头通过抛出异常的方式来实现校验token,导致走了网关兜底异常handler,通过改写response响应,导致跨域头没有塞回去。

我的观点:
1、网关filter不应该跟业务系统一样,直接抛出异常,而是直接返回异常码+异常信息+响应头。因为这里只是丢失了跨域头,那么其他什么灰度header标识,或者跟前端约定的东西都会丢失。我认为网关统一异常处理是作为最后兜底的方案去解决,不是作为业务异常来搞的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lJ8HF9Tb-1668392437440)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1e23fc213325468f90ed7f7afc667470~tplv-k3u1fbpfcp-watermark.image?)]

下课,觉得对你有帮助的,点点赞,关注下博主呗,感谢~

这篇关于小伙子把我坑了,改造网关filter,一直报跨域的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/160293

相关文章

Springboot处理跨域的实现方式(附Demo)

《Springboot处理跨域的实现方式(附Demo)》:本文主要介绍Springboot处理跨域的实现方式(附Demo),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录Springboot处理跨域的方式1. 基本知识2. @CrossOrigin3. 全局跨域设置4.

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言

Spring Boot拦截器Interceptor与过滤器Filter详细教程(示例详解)

《SpringBoot拦截器Interceptor与过滤器Filter详细教程(示例详解)》本文详细介绍了SpringBoot中的拦截器(Interceptor)和过滤器(Filter),包括它们的... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)详细教程1. 概述1

Spring MVC跨域问题及解决

《SpringMVC跨域问题及解决》:本文主要介绍SpringMVC跨域问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录跨域问题不同的域同源策略解决方法1.CORS2.jsONP3.局部解决方案4.全局解决方法总结跨域问题不同的域协议、域名、端口

dubbo3 filter(过滤器)如何自定义过滤器

《dubbo3filter(过滤器)如何自定义过滤器》dubbo3filter(过滤器)类似于javaweb中的filter和springmvc中的intercaptor,用于在请求发送前或到达前进... 目录dubbo3 filter(过滤器)简介dubbo 过滤器运行时机自定义 filter第一种 @A

关于Nginx跨域问题及解决方案(CORS)

《关于Nginx跨域问题及解决方案(CORS)》文章主要介绍了跨域资源共享(CORS)机制及其在现代Web开发中的重要性,通过Nginx,可以简单地解决跨域问题,适合新手学习和应用,文章详细讲解了CO... 目录一、概述二、什么是 CORS?三、常见的跨域场景四、Nginx 如何解决 CORS 问题?五、基

Java 8 Stream filter流式过滤器详解

《Java8Streamfilter流式过滤器详解》本文介绍了Java8的StreamAPI中的filter方法,展示了如何使用lambda表达式根据条件过滤流式数据,通过实际代码示例,展示了f... 目录引言 一.Java 8 Stream 的过滤器(filter)二.Java 8 的 filter、fi

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

proxy代理解决vue中跨域问题

vue.config.js module.exports = {...// webpack-dev-server 相关配置devServer: {host: '0.0.0.0',port: port,open: true,proxy: {'/api': {target: `https://vfadmin.insistence.tech/prod-api`,changeOrigin: true,p

计算机网络基础概念 交换机、路由器、网关、TBOX

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、VLAN是什么?二 、交换机三、路由器四、网关五、TBOXTelematics BOX,简称车载T-BOX,车联网系统包含四部分,主机、车载T-BOX、手机APP及后台系统。主机主要用于车内的影音娱乐,以及车辆信息显示;车载T-BOX主要用于和后台系统/手机APP通信,实现手机APP的车辆信息显示与控