Spring Cloud Gateway 读取请求传参

本文介绍了如何在Spring Cloud Gateway中处理API接口的身份校验,通过创建过滤器来读取请求的GET和POST参数。在获取参数后,将它们放入上下文以便后续的鉴权逻辑使用。解决方案包括定义了两个过滤器:GatewayContext和ApiRequestFilter,后者用于从上下文获取参数。同时,对于POST请求,需要重新构造请求体以保持数据完整。
摘要由CSDN通过智能技术生成

背景介绍

有个业务需求,要提供一套API接口给第三方调用。

在处理具体业务接口之前,设计上要先做个简单的鉴权,协商拟定了身份传参后,考虑到项目上已经用到了Spring Cloud Gateway ,就统一在网关模块做身份校验。

所以在服务端获取到请求的时候,要先拦截获取到请求传参,才能做后续的鉴权逻辑。

这里就需要解决一个问题:Spring Cloud Gateway 怎么读取请求传参?

搜索关键词:spring cloud gateway get request body

问题描述

问题:Spring Cloud Gateway 读取请求传参

这里只简单处理两种情况,get请求和post请求。

如果发现是get请求,就取url上的参数;
如果发现是post请求,就读取body的内容。

解决方案

参考 https://github.com/spring-cloud/spring-cloud-gateway/issues/747

定义了两个过滤器 filter,第一个过滤器ApiRequestFilter获取参数,放到上下文 GatewayContext

注意如果是POST请求,请求体读取完后,要重新构造,填回请求体中。

第二个过滤器ApiVerifyFilter, 从上下文可以直接获取到参数。

后面如果其他业务也有读取参数的需求,就直接从上下文获取,不用再重复写获取参数的逻辑。

实现代码

GatewayContext

@Data
public class GatewayContext {
   
    public static final String CACHE_GATEWAY_CONTEXT = "cacheGatewayContext";

    /**
     * cache json body
     */
    private String cacheBody;
    /**
     * cache form data
     */
    private MultiValueMap<String, Part> formData;
    /**
     * cache request path
     */
    private String path;
}

ApiRequestFilter


@Component
@Slf4j
public class ApiRequestFilter implements GlobalFilter, Ordered {
   

    private static AntPathMatcher antPathMatcher;

    static {
   
        antPathMatcher = new AntPathMatcher();
    }

    /**
     * default HttpMessageReader
     */
    private static final List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();

    private static final ResolvableType MULTIPART_DATA_TYPE = ResolvableType.forClassWithGenerics(MultiValueMap.class, String.class, Part.class);

    private static final Mono<MultiValueMap<String, Part>> EMPTY_MULTIPART_DATA = Mono.just(CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap<String, Part>(0))).cache();

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

        if(request.getMethod() == HttpMethod.GET){
   
            // get请求 处理参数
            return handleGetMethod(exchange, chain, request);
        }

        if(request.getMethod() == HttpMethod.POST){
   
            // post请求 处理参数
            return handlePostMethod(exchange, chain, request);
        }

        return chain.filter(exchange);
    }

    /**
     * get请求 处理参数
     * @param exchange
     * @param chain
     * @param request
     * @return
     */
    private Mono<Void> handleGetMethod(ServerWebExchange exchange, GatewayFilterChain chain, ServerHttpRequest request) {
   
        // TODO 暂时不做处理

        return chain.filter(exchange);
    }

    /**
     * post请求 校验参数
     * @param exchange
     * @param chain
     * @param request
     * @return
     */
    private Mono<Void> handlePostMethod(ServerWebExchange exchange, GatewayFilterChain chain, ServerHttpRequest request){
   
        GatewayContext gatewayContext = new GatewayContext();
        gatewayContext.setPath(request.getPath().pathWithinApplication().value())
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值