SpringCloud-Gateway网关实现入参统一解密

1.添加依赖

剩下的依赖自行添加...

    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

2.创建配置文件

这里我使用了Nacos,使用时需要添加Nacos依赖 及配置gateway路由配置

server:
  port: 8080

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: testservice
          uri: lb://testservice
          predicates:
            - Path=/test/**
          filters:
           - RequestSign

3.过滤器

直接看代码

import com.alibaba.fastjson.JSONObject;
import com.example.itvcommoncore.commonUtils.AESCoder;
import io.netty.buffer.ByteBufAllocator;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;


@Component
public class RequestSignGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {

    private static final Logger log = LoggerFactory.getLogger(RequestSignGatewayFilterFactory.class);

    @Override
    public GatewayFilter apply(Object config) {
        return  new RequestSignGatewayFilter();
    }


    public class RequestSignGatewayFilter implements GatewayFilter, Ordered {
        @SneakyThrows
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            ServerHttpRequest request = exchange.getRequest();
            String decryptedParam ="";
            if( exchange.getRequest().getMethod().matches(String.valueOf(HttpMethod.GET))){
                MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
                log.warn("request GET param :{}", queryParams.toString());
                decryptedParam=queryParams.getFirst("REQUEST");
                String decryptedValue = decrypt(decryptedParam);
                // 编码参数值
                String encodedDecryptedParam = URLEncoder.encode(decryptedValue, StandardCharsets.UTF_8);
                // 构建修改后的URI
                URI modifiedUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI())
                        .replaceQueryParam("REQUEST", encodedDecryptedParam)
                        .build(true)
                        .toUri();
                // 修改请求,设置新的URI
                ServerHttpRequest modifiedRequest = exchange.getRequest().mutate()
                        .uri(modifiedUri)
                        .build();
                // 用修改后的请求继续处理请求链
                return chain.filter(exchange.mutate().request(modifiedRequest).build());
            }else {
                //获取请求体数据
                AtomicReference<String> requestBody = new AtomicReference<>("");
                RecorderServerHttpRequestDecorator requestDecorator = new RecorderServerHttpRequestDecorator(request);
                Flux<DataBuffer> body = requestDecorator.getBody();
                body.subscribe(buffer -> {
                    CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
                    requestBody.set(charBuffer.toString());
                });
                //我这里是用request=参数  格式
                String decode = URLDecoder.decode(requestBody.get());
                String param = decode.replace("REQUEST=", "");
                log.warn("request POST param :{}",decode);
                decryptedParam=param;
                //解密的方法
                String decryptedValue = decrypt(decryptedParam);
                //编码参数值
                String encodedDecryptedParam = URLEncoder.encode(decryptedValue, StandardCharsets.UTF_8);
                //拼接新的请求体
                String str="REQUEST="+encodedDecryptedParam;
                DataBuffer bodyDataBuffer = stringBuffer(str);
                //添加到请求体
                Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
                MediaType contentType = request.getHeaders().getContentType();
                ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                        exchange.getRequest()) {
                    @Override
                    public HttpHeaders getHeaders() {
                        //重新设置请求头
                        HttpHeaders httpHeaders = new HttpHeaders();
                        int length = str.getBytes().length;
                        httpHeaders.putAll(super.getHeaders());
                        httpHeaders.remove(HttpHeaders.CONTENT_TYPE);
                        httpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
                        httpHeaders.setContentLength(length);
                        httpHeaders.set(HttpHeaders.CONTENT_TYPE, contentType.toString());
                        // 设置CONTENT_TYPE
                        return httpHeaders;
                    }
                    @Override
                    public Flux<DataBuffer> getBody() {
                        return bodyFlux;
                    }
                };
                return chain.filter(exchange.mutate().request(mutatedRequest).build());

            }
        }

        @Override
        public int getOrder() {
            return 2;
        }
    }

    /**
     * 转换参数的方法
     * @param value
     * @return
     */
    protected DataBuffer stringBuffer(String value) {
        byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
        NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
        DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
        buffer.write(bytes);
        return buffer;
    }

    /**
     * 解密方法
     * @param encryptedParam
     * @return
     */
    private String decrypt(String encryptedParam) {
        String returnResult = "";
        JSONObject json = JSONObject.parseObject(encryptedParam);
        //我的参数在data里
        String encrypt = json.getString("data");
        try {
        //解密
            returnResult = AESCoder.decryptAES(encrypt, "test");
            return returnResult;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnResult;
    }

    public class RecorderServerHttpRequestDecorator  extends ServerHttpRequestDecorator {
        private final List<DataBuffer> dataBuffers = new ArrayList<>();
        public RecorderServerHttpRequestDecorator(ServerHttpRequest delegate) {
            super(delegate);
            super.getBody().map(dataBuffer -> {
                dataBuffers.add(dataBuffer);
                return dataBuffer;
            }).subscribe();
        }

        @Override
        public Flux<DataBuffer> getBody() {
            return copy();
        }

        private Flux<DataBuffer> copy() {
            return Flux.fromIterable(dataBuffers)
                    .map(buf -> buf.factory().wrap(buf.asByteBuffer()));
        }
    }
}

4.接口层

这里要新建一个testservice服务,在testservice工程里写这个接口

@RestController
public class Test{

    @GetMapping("hello") //这里根据需要更换get、post请求
    public String test(@RequestParam("REQUEST")String result){
        System.out.println(result);
        return result;
        
        }

}

配置文件:

spring:
  application:
    name: testservice
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
        group: test
        prefix: test
server:
  servlet:
    context-path: /test

5. 测试

我这里是编写了一个测试类

 public static void main(String[] args) throws Exception {
        try {
            JSONObject jo = new JSONObject();
            jo.put("param1", "测试啊");
            jo.put("param2", "1");
            JSONObject reqjo = new JSONObject();
            String params = "";
            //加密请求参数
            encrypt = AESCoder.encrypt(jo.toString(), "test");
            reqjo.put("data", params );
            String responseBody = "";
            // 请求参数
                String sendparam= "REQUEST="
                        + URLEncoder.encode(reqjo.toString(), "UTF-8");
            String localUrl="htp://localhost:8081/test/hello"

                HttpClientCommon hc = new HttpClientCommon();
                responseBody = hc.responseBody(localUrl + "?" + sendparam, sendparam);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(responseBody);
            JSONObject json = JSONObject.fromObject(responseBody);
            String res = (String) json.get("RESPONSE=");
            res = URLDecoder.decode(res, "UTF-8");
            byte[] bytes = AESCoder.decrypt(res, "test");
            String returnResult = new String(bytes, "UTF-8");
            System.out.println("返回参数:" + returnResult);
        }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringCloud Gateway是一个基于Spring Cloud的全新项目,它是基于Spring 5.0、Spring Boot 2.0和Project Reactor等技术开发的网关。它的主要目标是为微服务架构提供一种简单有效的统一API路由管理方式。SpringCloud Gateway具有许多特性,包括动态路由、断路器功能、服务发现功能、请求限流功能和支持路径重写等。它是基于WebFlux框架实现的,底层使用了高性能的Reactor模式通信框架Netty。总之,SpringCloud Gateway是一个功能强大且易于使用的网关,可用于构建和管理微服务架构中的API路由。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [springcloud入门——gateway](https://blog.csdn.net/tang_seven/article/details/118523647)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [springcloudGateWay](https://blog.csdn.net/qq_35512802/article/details/122049808)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值