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


    1.添加依赖

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

    1. <dependency>
    2. <groupId>org.springframework.cloud</groupId>
    3. <artifactId>spring-cloud-starter-gateway</artifactId>
    4. </dependency>

    2.创建配置文件

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

    1. server:
    2. port: 8080
    3. spring:
    4. application:
    5. name: gateway-service
    6. cloud:
    7. nacos:
    8. discovery:
    9. server-addr: 127.0.0.1:8848
    10. config:
    11. server-addr: 127.0.0.1:8848
    12. file-extension: yaml
    13. gateway:
    14. discovery:
    15. locator:
    16. enabled: true
    17. routes:
    18. - id: testservice
    19. uri: lb://testservice
    20. predicates:
    21. - Path=/test/**
    22. filters:
    23. - RequestSign

    3.过滤器

    直接看代码

    1. import com.alibaba.fastjson.JSONObject;
    2. import com.example.itvcommoncore.commonUtils.AESCoder;
    3. import io.netty.buffer.ByteBufAllocator;
    4. import org.springframework.core.io.buffer.NettyDataBufferFactory;
    5. import org.springframework.http.HttpHeaders;
    6. import org.springframework.http.MediaType;
    7. import org.springframework.http.server.reactive.ServerHttpRequest;
    8. import lombok.SneakyThrows;
    9. import org.slf4j.Logger;
    10. import org.slf4j.LoggerFactory;
    11. import org.springframework.cloud.gateway.filter.GatewayFilter;
    12. import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    13. import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
    14. import org.springframework.core.Ordered;
    15. import org.springframework.core.io.buffer.DataBuffer;
    16. import org.springframework.http.HttpMethod;
    17. import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
    18. import org.springframework.stereotype.Component;
    19. import org.springframework.util.MultiValueMap;
    20. import org.springframework.web.server.ServerWebExchange;
    21. import org.springframework.web.util.UriComponentsBuilder;
    22. import reactor.core.publisher.Flux;
    23. import reactor.core.publisher.Mono;
    24. import java.net.URI;
    25. import java.net.URLDecoder;
    26. import java.net.URLEncoder;
    27. import java.nio.CharBuffer;
    28. import java.nio.charset.StandardCharsets;
    29. import java.util.ArrayList;
    30. import java.util.List;
    31. import java.util.concurrent.atomic.AtomicReference;
    32. @Component
    33. public class RequestSignGatewayFilterFactory extends AbstractGatewayFilterFactory {
    34. private static final Logger log = LoggerFactory.getLogger(RequestSignGatewayFilterFactory.class);
    35. @Override
    36. public GatewayFilter apply(Object config) {
    37. return new RequestSignGatewayFilter();
    38. }
    39. public class RequestSignGatewayFilter implements GatewayFilter, Ordered {
    40. @SneakyThrows
    41. @Override
    42. public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    43. ServerHttpRequest request = exchange.getRequest();
    44. String decryptedParam ="";
    45. if( exchange.getRequest().getMethod().matches(String.valueOf(HttpMethod.GET))){
    46. MultiValueMap queryParams = exchange.getRequest().getQueryParams();
    47. log.warn("request GET param :{}", queryParams.toString());
    48. decryptedParam=queryParams.getFirst("REQUEST");
    49. String decryptedValue = decrypt(decryptedParam);
    50. // 编码参数值
    51. String encodedDecryptedParam = URLEncoder.encode(decryptedValue, StandardCharsets.UTF_8);
    52. // 构建修改后的URI
    53. URI modifiedUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI())
    54. .replaceQueryParam("REQUEST", encodedDecryptedParam)
    55. .build(true)
    56. .toUri();
    57. // 修改请求,设置新的URI
    58. ServerHttpRequest modifiedRequest = exchange.getRequest().mutate()
    59. .uri(modifiedUri)
    60. .build();
    61. // 用修改后的请求继续处理请求链
    62. return chain.filter(exchange.mutate().request(modifiedRequest).build());
    63. }else {
    64. //获取请求体数据
    65. AtomicReference requestBody = new AtomicReference<>("");
    66. RecorderServerHttpRequestDecorator requestDecorator = new RecorderServerHttpRequestDecorator(request);
    67. Flux body = requestDecorator.getBody();
    68. body.subscribe(buffer -> {
    69. CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
    70. requestBody.set(charBuffer.toString());
    71. });
    72. //我这里是用request=参数 格式
    73. String decode = URLDecoder.decode(requestBody.get());
    74. String param = decode.replace("REQUEST=", "");
    75. log.warn("request POST param :{}",decode);
    76. decryptedParam=param;
    77. //解密的方法
    78. String decryptedValue = decrypt(decryptedParam);
    79. //编码参数值
    80. String encodedDecryptedParam = URLEncoder.encode(decryptedValue, StandardCharsets.UTF_8);
    81. //拼接新的请求体
    82. String str="REQUEST="+encodedDecryptedParam;
    83. DataBuffer bodyDataBuffer = stringBuffer(str);
    84. //添加到请求体
    85. Flux bodyFlux = Flux.just(bodyDataBuffer);
    86. MediaType contentType = request.getHeaders().getContentType();
    87. ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
    88. exchange.getRequest()) {
    89. @Override
    90. public HttpHeaders getHeaders() {
    91. //重新设置请求头
    92. HttpHeaders httpHeaders = new HttpHeaders();
    93. int length = str.getBytes().length;
    94. httpHeaders.putAll(super.getHeaders());
    95. httpHeaders.remove(HttpHeaders.CONTENT_TYPE);
    96. httpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
    97. httpHeaders.setContentLength(length);
    98. httpHeaders.set(HttpHeaders.CONTENT_TYPE, contentType.toString());
    99. // 设置CONTENT_TYPE
    100. return httpHeaders;
    101. }
    102. @Override
    103. public Flux getBody() {
    104. return bodyFlux;
    105. }
    106. };
    107. return chain.filter(exchange.mutate().request(mutatedRequest).build());
    108. }
    109. }
    110. @Override
    111. public int getOrder() {
    112. return 2;
    113. }
    114. }
    115. /**
    116. * 转换参数的方法
    117. * @param value
    118. * @return
    119. */
    120. protected DataBuffer stringBuffer(String value) {
    121. byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
    122. NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
    123. DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
    124. buffer.write(bytes);
    125. return buffer;
    126. }
    127. /**
    128. * 解密方法
    129. * @param encryptedParam
    130. * @return
    131. */
    132. private String decrypt(String encryptedParam) {
    133. String returnResult = "";
    134. JSONObject json = JSONObject.parseObject(encryptedParam);
    135. //我的参数在data里
    136. String encrypt = json.getString("data");
    137. try {
    138. //解密
    139. returnResult = AESCoder.decryptAES(encrypt, "test");
    140. return returnResult;
    141. } catch (Exception e) {
    142. e.printStackTrace();
    143. }
    144. return returnResult;
    145. }
    146. public class RecorderServerHttpRequestDecorator extends ServerHttpRequestDecorator {
    147. private final List dataBuffers = new ArrayList<>();
    148. public RecorderServerHttpRequestDecorator(ServerHttpRequest delegate) {
    149. super(delegate);
    150. super.getBody().map(dataBuffer -> {
    151. dataBuffers.add(dataBuffer);
    152. return dataBuffer;
    153. }).subscribe();
    154. }
    155. @Override
    156. public Flux getBody() {
    157. return copy();
    158. }
    159. private Flux copy() {
    160. return Flux.fromIterable(dataBuffers)
    161. .map(buf -> buf.factory().wrap(buf.asByteBuffer()));
    162. }
    163. }
    164. }
    165. 4.接口层

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

      1. @RestController
      2. public class Test{
      3. @GetMapping("hello") //这里根据需要更换get、post请求
      4. public String test(@RequestParam("REQUEST")String result){
      5. System.out.println(result);
      6. return result;
      7. }
      8. }

      配置文件:

      1. spring:
      2. application:
      3. name: testservice
      4. cloud:
      5. nacos:
      6. discovery:
      7. server-addr: 127.0.0.1:8848
      8. config:
      9. server-addr: 127.0.0.1:8848
      10. file-extension: yaml
      11. group: test
      12. prefix: test
      13. server:
      14. servlet:
      15. context-path: /test

      5. 测试

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

      1. public static void main(String[] args) throws Exception {
      2. try {
      3. JSONObject jo = new JSONObject();
      4. jo.put("param1", "测试啊");
      5. jo.put("param2", "1");
      6. JSONObject reqjo = new JSONObject();
      7. String params = "";
      8. //加密请求参数
      9. encrypt = AESCoder.encrypt(jo.toString(), "test");
      10. reqjo.put("data", params );
      11. String responseBody = "";
      12. // 请求参数
      13. String sendparam= "REQUEST="
      14. + URLEncoder.encode(reqjo.toString(), "UTF-8");
      15. String localUrl="htp://localhost:8081/test/hello"
      16. HttpClientCommon hc = new HttpClientCommon();
      17. responseBody = hc.responseBody(localUrl + "?" + sendparam, sendparam);
      18. } catch (Exception e) {
      19. e.printStackTrace();
      20. }
      21. System.out.println(responseBody);
      22. JSONObject json = JSONObject.fromObject(responseBody);
      23. String res = (String) json.get("RESPONSE=");
      24. res = URLDecoder.decode(res, "UTF-8");
      25. byte[] bytes = AESCoder.decrypt(res, "test");
      26. String returnResult = new String(bytes, "UTF-8");
      27. System.out.println("返回参数:" + returnResult);
      28. }

    166. 相关阅读:
      【Go语言】切片的扩容
      面试官:介绍一下 Redis 三种集群模式
      G1回收器参数设置
      玩一玩 Ubuntu 下的 VSCode 编程
      【回归预测】基于萤火虫算法优化模糊实现数据回归预测附matlab代码
      Java职业发展
      说说教育机构教学课程视频加密是如何实现的?
      Oracle Schema Only账户
      leetcode 15. 三数之和
      深度学习之使用Milvus向量数据库实战图搜图
    167. 原文地址:https://blog.csdn.net/RHHcainiao/article/details/132868757