SpringCloud系列之自定义GatewayFilterFactory

SpringCloud系列之自定义GatewayFilterFactory,第1张

SpringCloud系列之自定义GatewayFilterFactory

SpringCloud系列之自定义GatewayFilterFactory

学习目的:

  • 知道创建一个网关sample
  • 知道网关的基本配置
  • 知道自定义GatewayFilterFactory类

环境准备:

  • JDK 1.8
  • SpringBoot2.2.3
  • SpringCloud(Hoxton.SR7)
  • Maven 3.2+
  • 开发工具
    • IntelliJ IDEA
    • smartGit

新增SpringBoot Initializer项目:New Module->Spring Initializer,选择jdk版本,至少jdk8

packaging选择jar,java version选择jdk8的,然后点next

选择Gateway的依赖,选择之后会自动加上对应pom配置

新建项目之后,检查pom是否有spring-cloud-starter-gateway


  org.springframework.cloud
  spring-cloud-starter-gateway

如果不通过idea的Spring Initializer新建项目的,需要自己加上:


        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

网关配置,业务场景,一个第三方的接口,经过网关路由之后需要在request header里加上一些校验参数

spring:
  application:
    name: api-gateway  # 指定application name
  cloud:
    gateway:
      routes:
        - id: get_user_info
          uri: http://127.0.0.1:8083
          predicates:
          - Path=/api/findUser
          filters:
          - AddRequestHeader=passToken,a68f3eac-5b9c-4fc1-a900-98ee18574576
          # FilterFactory名为自定义类名前几个
          - name: Custom
            args:
              passid: 7a11600c-403c-4260-9165-659e138ada9c
              serviceId: d8c6ce4c-1b2c-4826-9044-4197d17aad87

自定义一个GatewayFilterFactory,命名后面统一加上GatewayFilterFactory,自定义的字段配在yml的filters.name

package com.example.springcloud.gateway.filter.factories;

import com.example.springcloud.gateway.util.EncryptUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;

import java.util.Date;


@Slf4j
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory
implements Ordered {

    public CustomGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return ((exchange, chain) -> {
            String passToken = exchange.getRequest().getHeaders().getFirst("passToken");
            log.info("passToken:{}" , passToken);
            long now = new Date().getTime();
            String timestamp = Long.toString((long)Math.floor(now/1000));
            String signature = "";
            try {
                signature = EncryptUtils.toSHA256(timestamp + passToken + timestamp);
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("signature:{}" , signature);
            ServerHttpRequest request = exchange.getRequest().mutate()
                    .header("passid", config.getPassid())
                    .header("serviceId", config.getServiceId())
                    .header("signature", signature)
                    .build();
            log.info("passid:{}" , config.getPassid());
            log.info("serviceId:{}" , config.getServiceId());
            return chain.filter(exchange.mutate().request(request).build());
        });
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }


    @Data
    public static class Config {
        private String passid;
        private String serviceId;
    }
}

过滤器将在较早的阶段执行其“pre”逻辑,但稍后会调用它的“post”实现:

官网的图例:首先客户端请求都会先经过Gateway Handler Mapping,匹配上就通过Gateway Web Handler转给过滤器处理,过滤器分为PreFilter(前置过滤器)、PostFilter(后置过滤器)。过滤器由虚线分隔的原因是,筛选器可以在发送代理请求之前和之后运行逻辑。所有“前置”过滤器逻辑均被执行。然后发出代理请求。发出代理请求后,将运行“后置”过滤器逻辑

import java.security.MessageDigest;


public class EncryptUtils {

	
	public static String toSHA256(String str) throws Exception {
		MessageDigest messageDigest;
		String encodeStr = "";
		try {
			messageDigest = MessageDigest.getInstance("SHA-256");
			messageDigest.update(str.getBytes("UTF-8"));
			encodeStr = byte2Hex(messageDigest.digest());
		} catch (Exception e) {
			throw e;
		}
		return encodeStr;
	}

	
	protected static String byte2Hex(byte[] bytes) {
		StringBuffer stringBuffer = new StringBuffer();
		String temp = null;
		for (int i = 0; i < bytes.length; i++) {
			temp = Integer.toHexString(bytes[i] & 0xFF);
			if (temp.length() == 1) {
				stringBuffer.append("0");
			}
			stringBuffer.append(temp);
		}
		return stringBuffer.toString();
	}
}

控制台打印:

signature:72bdd60d2fc6f115eabda1ced766c0c0aa7397521d653977b2fd15d6c6978587
passid:7a11600c-403c-4260-9165-659e138ada9c
serviceId:d8c6ce4c-1b2c-4826-9044-4197d17aad87

然后去第三方接口看请求header参数,可以带过来

注意:如果网关配置不起效,可以尝试设置ordered确定优先级,有多个配置,可以将配置位置适当挪前点

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5671485.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存