客户端与微服务之间的桥梁---网关

当我们创建好了N多个微服务或者微服务的实例之后,每个服务暴露出不同的端口地址,一般对于客户端请求,只需要请求一个端口,要隔离客户端和微服务的直接关系,保证微服务的安全性和灵活性,避免敏感信息的泄露。这时就需要网关。

网关

例如,我们在外人和村庄之间建立了一座桥梁,在桥上有一个管理员(守卫),他负责检查每个想要过桥的人。如果检查合格,他会允许通过,并告诉你要找的人的住处;如果不合格,则不允许通过。

网关充当了统一的接入点(桥梁),客户端仅需通过网关的固定端口或地址进行访问,无需了解各个微服务的具体端口和地址。网关内部根据配置的服务路由规则进行操作,一旦请求符合这些规则,网关便会从Nacos注册中心获取相应的服务地址,并将客户端的请求路由至指定的微服务。其他功能如身份校验,限流,路由转发,请求过滤等。

配置网关

将网关作为一个独立的模块,服务部署。配置启动类,引入依赖,配置路由规则即可。

到此启动网关后, 通过8080及具体的路径就可以访问到任何一个微服务了,具体是哪个是由负载均衡决定好了。但是,目前是不安全的,因为没有做身份校验。我们希望的是请求必须经过网关处理。

配置网关内部过滤拦截器

可以在网关内部声明一个全局过滤器专门处理登录校验,这个自定义过滤器要实现GlobalFilter接口,并实现其方法。过滤器有很多个,是依次链式调用的,直到最后一个。

全局过滤器链的最后一个执行的过滤器, 通常是 NettyWriteResponseFilter。它执行完了,这个过滤过程也就结束了,这个过滤器的作用是负责将响应数据写回给客户端,它是默认过滤器链中最末端的一个过滤器。对于前置过滤器,会在请求到达微服务目标之前执行,可以实现Ordered接口给过滤器设置优先级,数字越小,优先级越高,越先执行。

大致步骤:

1,需要判断当前路径是否需要拦截,不需要就放行。
java 复制代码
@Component
@RequiredArgsConstructor
public class MyAuthGlobalFilter implements GlobalFilter, Ordered {
    private final AuthProperties authProperties;
    private final static AntPathMatcher pathMatcher = new AntPathMatcher();
    

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
     
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        List<String> excludePaths = authProperties.getExcludePaths();

        // 判断当前路径是否需要拦截校验,不需要就放行
        if (checkUrl(excludePaths, path)) {
            return chain.filter(exchange);
        }

AuthProperties中放的就是自定义好的不需要拦截的路径。这里需要的是将当前请求的路径与不需要拦截的路径进行匹配,True就放行。自定义一个匹配方法并使用Spring提供的AntPathMatcher进行路径匹配。

(放行:网关内部有很多个拦截过滤器,是依次执行调用的,实际上是调用下一个拦截器,然后将当前请求响应的上下文对象exchange传递过去)

2,如果需要拦截,就获取请求中的token信息进行校验

不仅要验证获取请求头中是否有相应字段,还要验证token是否有结果,以及是否能够成功解析,不管哪一步失败了,我们就向客户端响应失败的信息(响应状态码)。setComplete() 方法表示响应已完成。它会立即返回并结束当前请求的处理流程,不再执行后续的过滤器或业务逻辑。setComplete() 的返回值是一个 Mono<Void>,这是 Reactor 中的一个信号,表示响应结束。

java 复制代码
String token = null;
        List<String> authorization = request.getHeaders().get("authorization");
        if (authorization != null && !authorization.isEmpty()) {
            token = authorization.get(0);
        }

        // 校验 token
        Long parseToken=null;
        if (token != null && !token.isEmpty()) {
             parseToken = jwtTool.parseToken(token);
            if (parseToken == null) {
                // Token 校验失败,返回 401 未授权
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
        } else {
            // Token 为空,返回 401 未授权
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

此时访问8080/items/page有结果,因为它无需拦截:

访问另外一个被拦截的就没有结果8080/carts:

相关推荐
电商API_1800790524735 分钟前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫
一点程序1 小时前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
C雨后彩虹1 小时前
计算疫情扩散时间
java·数据结构·算法·华为·面试
2601_949809591 小时前
flutter_for_openharmony家庭相册app实战+我的Tab实现
java·javascript·flutter
vx_BS813301 小时前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_949868361 小时前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
达文汐2 小时前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
培风图南以星河揽胜2 小时前
Java版LeetCode热题100之零钱兑换:动态规划经典问题深度解析
java·leetcode·动态规划
启山智软2 小时前
【中大企业选择源码部署商城系统】
java·spring·商城开发
我真的是大笨蛋2 小时前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化