Gateway-过滤器 - 教程

1.定义

一种在执行路由转发前后,用于拦截和修改传入的 HTTP 请求或返回的 HTTP 响应的组件。可能把它想象成一个 AOP(面向切面编程)的概念,在请求的生命周期中的特定点插入自定义逻辑。就是网关过滤器

2.功能

  • 身份认证与安全: 验证请求的 Token(如 JWT),拒绝非法请求。
  • 监控与指标收集: 记录请求的响应时间、状态码,用于性能监控(如集成 Prometheus)。
  • 动态路由: 根据请求内容(如 Header、路径)将请求路由到不同的服务实例。
  • 负载均衡: 在可用服务实例之间分配流量。
  • 请求限流与熔断: 限制单位时间内的请求数量,或在后端服务不可用时提供降级响应。
  • 请求/响应转换: 修改请求头、请求体,或者修改响应头、响应体。
  • 日志记录: 记录详细的访问日志和审计信息。

3. 类型

在 Spring Cloud Gateway 中,过滤器主要分为两种:

a) 全局过滤器 (Global Filters)
  • 作用范围: 应用于所有进入网关的路由,无需安装,自动生效。
  • 用途: 搭建全局性的能力,如全局认证、全局日志、全局跨域部署等。
  • 实现方式: 实现 GlobalFilter 接口,并声明为 @Component 或通过配置类添加。
b)实现:RtGlobalFilter

连包带类创建filter.RtGlobalFilter,完成GlobalFilter接口,这里以计算响应时间为例编码。

编写完计算响应耗时逻辑后,通过Component注解,将全局过滤器交给Spring容器管理

接着开启任意一个order微服务和Gateway微服务

浏览器访问http://localhost/api/order/readDb

然后允许看到,在控制台中已经成功计算了该请求-响应的耗时,19ms。

c) 网关过滤器 (Gateway Filters)
  • 作用范围: 需要通过配置应用于特定路由。通常在路由配置中通过 filters 字段声明。
  • 用途: 实现针对某个或某组路由的特定功能,如为某个服务添加请求头、重写路径等。
d) 实现:路径重写过滤器

我们首先注释ordercontroller的接口路径

启动所有微服务

启动完毕后,浏览器访问localhost/api/order/readDB

行看到返回了404,源于api/order接口被注释掉了

接下来,我们就采用路径重写过滤器来解决这个问题

- RewritePath=/api/order/(?<segment>.*),/${segment}:

它匹配任何以 /api/order/ 开头的路径

将 /api/order/ 之后的所有内容捕获到一个名为 segment 的分组中

(?<segment>.*) 是正则表达式的命名捕获组,用于匹配任意字符

例如:

捕获前 ——> 捕获后

/api/order/readDb → /readDb

/api/order/123/details → /123/details

/api/order/search?status=pending → /search?status=pending

然后,大家再来测试一下,看看是否行成功访问

通过将它们捕获到分组中,便于构建。就是可能看到访问成功了,这就是路径重写过滤器的强大,它使得客户端请求的路径与网关对外暴露的路径能够不同,网关在转发前会将其“重写”为后端服务能够识别的正确路径。它还避免将内部微服务的复杂结构暴露给外部客户端,增强安全性。外部客户端无法看到内部完整接口,隐藏了内部核心接口。它也使得开发者在研发接口的时候,不用写多个重复的RequestMapping("/**/*"),而

此外, 过滤器还提供了添加响应头响应参数等机制,下面我们来简单试试

这次我们来以writeDb测试,浏览器访问后,按F12,查看writeDb请求标头,我们可以看到响应标头携带了我们刚才在配置文件中添加的参数,X-Response-Default-Foo, Default-Bar

e) 自定义过滤器 (Custom Filters)

● 作用范围: 由开发者精确定义,可应用于单个路由、一组路由或全局。其作用域借助配置或注解灵活控制。
● 用途: 实现特定的业务逻辑,如接口权限校验、请求参数加解密、流量染色、特定API的限流等。
● 实现方式: 通常通过实现 GatewayFilter 接口或继承 AbstractGatewayFilterFactory 类来创建,并通过配置文件的 filters 项或代码方式绑定到指定路由。

f)实现:OnceTokenGatewayFilterFactory过滤器工厂

我们首先来看一下Spring Cloud Gateway 内置的过滤器工厂AddResponseHeaderGatewayFilterFactory,看看我们自定义一个过滤器工厂得哪些操作

通过源码大家行知道,看看我们自定义一个过滤器工厂需要继承抽象类AbstractNameValueGatewayFilterFactory,定义配置类,提供构造函数,搭建apply()办法等

首先,需要在配置文件中添加一个自定义过滤器,这里以JWT令牌为例

引入JWT依赖

创建工具类,JWTutils

package com.atguigu.gateway.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JWTutils {
    private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    private static final long EXPIRATION_TIME = 86400000; // 24小时
    /**
     * 生成 JWT
     * @param claims 自定义声明
     * @return JWT 字符串
     */
    public static String generateToken(Map claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SECRET_KEY)
                .compact();
    }
    /**
     * 验证 JWT 并返回 Claims
     * @param token JWT 字符串
     * @return Claims 对象
     */
    public static Claims validateToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(SECRET_KEY)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }
    /**
     * 检查 JWT 是否过期
     * @param claims Claims 对象
     * @return 是否过期
     */
    public static boolean isTokenExpired(Claims claims) {
        return claims.getExpiration().before(new Date());
    }
    /**
     * 生成默认的 Claims(包含用户名和角色)
     * @param username 用户名
     * @param role 角色
     * @return Claims Map
     */
    public static Map generateClaims(String username, String role) {
        Map claims = new HashMap<>();
        claims.put("username", username);
        claims.put("role", role);
        return claims;
    }
}

创建 OnceTokenGatewayFilterFactory继承AbstractNameValueGatewayFilterFactory,并实现apply方法,编写相关逻辑

启动订单微服务和网关微服务

浏览器访问,同时F12打开开发者工具查看,readDb请求--响应

可以看到请求头中已经携带了Token,通过控制台中我们也可能看到响应头和token。

4.总结

特性

全局过滤器 (Global Filter)

网关过滤器 (Gateway Filter)

作用范围

所有路由

特定配置的路由

配置方式

代码声明(@Component

配置文件或代码

常见用途

认证、安全、全局日志、跨域

路径重写、服务特定的头修改、流量控制

灵活性

低(全局生效)

高(可针对不同路由定制)

过滤器是网关的“肌肉”和“大脑”,它将网关从一个简单的路由器转变为一个强大的策略执行点,是构建现代化、可观测、安全的微服务架构的基石。

posted on 2025-10-04 17:31  slgkaifa  阅读(2)  评论(0)    收藏  举报

导航