# 概述

当需要拦截请求进行处理,再向后续逻辑传递处理结果,或者根据后续逻辑的处理情况响应请求时,可通过fizz插件机制实现。

插件:

1、类似spring的WebFilter,是fizz内部的WebFilter,由fizz调度。 2、对不同的请求,可配置不同的上下文参数,可通过manager完成配置。

插件的开发和应用,分gateway开发、manager配置两部分,下面以一个例子介绍:假设用户登录系统后,系统生成对应的 token,以 token (key) -> 用户 id (value) 的形式存储于 redis,用户的后续请求需带上 token,否则无法访问系统逻辑,若所带 token 在系统中不存在,也拒绝访问。

# gateway开发

实现

public interface FizzPluginFilter {
    public Mono<Void> filter(ServerWebExchange exchange, Map<String, Object> config);
}

即定义了一个插件,config接收管理后台(manager)配置的参数。

例子插件:

@Component(RedisAuthPlugin.REDIS_AUTH_PLUGIN) // 插件id,必须
public class RedisAuthPlugin implements FizzPluginFilter {

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

    public static final String REDIS_AUTH_PLUGIN = "redisAuthPlugin"; // 管理后台据此设置插件id

    @Resource(name = RedisConfig.REACTIVE_STRING_REDIS_TEMPLATE)
    private ReactiveStringRedisTemplate redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, Map<String, Object> config) {
        String customConfig = (String) config.get(PluginConfig.CUSTOM_CONFIG); // 获取管理后台自定义的插件配置
        log.info("custom plugin config: " + customConfig);
        doSomething();

        String tk = exchange.getRequest().getQueryParams().getFirst("token"); // 获取客户端请求携带的 token
        return
                redisTemplate.opsForValue().get(tk).defaultIfEmpty(Constants.Symbol.EMPTY) // 检查 redis 中是否存在 tk
                        .flatMap(
                                user -> {
                                    if (user == Constants.Symbol.EMPTY) {
                                        return WebUtils.buildDirectResponse(exchange, HttpStatus.OK, null, "不存在 token " + tk); // 拒绝当前请求
                                    } else {
                                        exchange.getAttributes().put("11", "22"); // 往后续插件或逻辑传递参数
                                        Mono next = FizzPluginFilterChain.next(exchange); // 执行下一个插件或后续逻辑
                                        return next.defaultIfEmpty(ReactorUtils.NULL).flatMap(
                                                nil -> {
                                                    doAfterNext(); // 当 next 完成时执行一些逻辑
                                                    return Mono.empty();
                                                }
                                        );
                                    }
                                }
                        );
    }

    public void doSomething() {
    }

    public void doAfterNext() {
        log.info("do after next plugin done");
    }
}

例子代码:https://github.com/wehotel/fizz-examples/tree/master/fizz-example-plugin/redis-auth-plugin,例子的运行等,参其中的 README.md,为方便演示,例子不对接管理后台,相关参数配在例子代码中。

# manager配置

1、新增插件定义

2、应用插件

编辑路由:

在RedisAuthPlugin中,可通过config.get("param6") 访问参数6

上次更新: 2021-7-27 13:9