本文正在参加「金石计划 . 分割6万现金大奖」

闲聊


1、项目研发负责人需要具有自动性

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

【履行者视点】:我完成某项使命,I do it~

【owner视点】入手使命前,这个使命为了处理什么东西(中心价值)?它会引发你的考虑,便是我有没有其他更好的计划去处理这个问题,其次是在施行前考虑可行性、风险、扩展点。使命履行中,项目进度是不是在预期内,然后遇到什么问题需要自动寻求协助。使命完成后,咱们做这个项目它有没有发挥应有的价值,这时就要调查项目运转状况、事务状况,如果它是一个继续的进程,那么咱们还要规划下一步内容。

我觉得这是我在当项目负载负责人的时分学习到的,我能够清晰调查到许多项目半死不活,就它仅仅服务于当下,可能上线后没有多少人去用它,它的价值彻底没有发挥出来,just 一个摆设!

坚持做正确的事 –马斯克

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

前语


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

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

排查进程


1. 第一步:我调查网关跨域装备是否有问题

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

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

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

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

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

咱们看到是能正常回来的,可是!是反常,验证已失效,请重新登录。

3. 第二步,检查网关跨域装备

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

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

@Slf4j
public class XxxFilter extends AbstractErrorWebExceptionHandler implements Ordered {
    @Override
    protected 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反常抛出的时分才会被捕获。报错的接口却是走这个反常,问题慢慢揭开面纱~

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

4. 第三步:检查接口的归属以及完成

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

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

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

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

小伙子把我坑了,改造网关filter,一直报跨域
当我看到办法里头的完成的时分,我就觉得坏事了,由于咱们网关filter是不会这么写的,直接抛出反常。

why?

事务体系咱们习惯是throw new xxException对吧,这个没有错,由于事务体系有一致反常捕获。小伙子改造网关filter验证,也认为网关有反常捕获对吧。

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

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

留意这儿重写了response,导致header头的跨域头丢掉了。

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

留意这儿是强行加上跨域头,你想想网关怎样能够有抛出反常呢?它只能有反常呼应,不能直接抛出反常,它是两回事,前者是封装反常码、反常信息,后者是直接抛出反常,他们区别便是500,体系反常,那是万不得已才去大局捕获的,事务体系还能理解,可是网关的话人家捕获反常是为了避免如果,你偏偏要去经过抛出反常来处理,去走最后兜底计划。

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

到这儿咱们就处理了跨域问题

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


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

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

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

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

  • 灰度计划-svc环境完成计划以及网关源码剖析

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

回忆


导致的原因其实便是由于接入一致登录的时分,有些权限接口是白名单,经过网关filter来鉴权,可是呢,里头经过抛出反常的办法来完成校验token,导致走了网关兜底反常handler,经过改写response呼应,导致跨域头没有塞回去。

我的观念: 1、网关filter不该该跟事务系一致样,直接抛出反常,而是直接回来反常码+反常信息+呼应头。由于这儿仅仅丢掉了跨域头,那么其他什么灰度header标识,或者跟前端约好的东西都会丢掉。我认为网关一致反常处理是作为最后兜底的计划去处理,不是作为事务反常来搞的

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

下课觉得对你有协助的,点点赞,重视下博主呗,感谢