网关是响应式的，但是目前大量的签权接口及背后的技术大多是同步的。

* 尽量使用原生异步的（或响应式的）接口
* 当没有时
  * 且涉及 io的，把同步转异步，并发生在订阅时
  * 如果不涉及 io，按正常处理




### 1、简单鉴权参考（不涉及同步 io）

此示例，检查有没有 "TOKEN" 的头信息，如果没有就 401 输出并中止。


```java
@Component(index = -9) //index 为可选
public class CloudGatewayAuthFilter implements CloudGatewayFilter {
    @Override
    public Completable doFilter(ExContext ctx, ExFilterChain chain) {
        String token = ctx.rawHeader("TOKEN");

        if (token == null) {
            //如果没有 TOKEN 表示失败
            
            //方式1：通过格式化内容输出
            String resultStr = ONode.stringify(Result.failure(401, "签权失败"));

            ctx.newResponse().header("Content-Type", "application/json;charset=UTF-8");
            ctx.newResponse().body(Buffer.buffer(resultStr));
            return Completable.complete();
            
            //方式2：传递异常（交给异常过滤器统一处理）
            //return Completable.error(new StatusException("No authority",401));
        }

        return chain.doFilter(ctx);
    }
}
```


### 2、对接 sa-token 鉴权参考（会涉及同步 io）

sa-token 的鉴权行为：

* 会涉及同步io（redis dao），需要使用异步的方式，避免卡住底层的事件循环器
* 签权时还可能会直接输出响应（需要检查，如果已输出说明鉴权未通过）
* 内部是基于经典的 Context 接口适配的（需要用到 `ExContext:toContext()` ）

可以使用新接口 `CloudGatewayFilterSync` 或 `ExFilterSync`（v3.2.1 后支持），简化开发。


具体对接参考：

```java
@Component(index = -9) //index 为可选
public class CloudGatewayFilterImpl implements CloudGatewayFilterSync {
    /**
     * @return 是否继续
     */
    @Override
    public boolean doFilterSync(ExContext ctx) throws Throwable {
        //1.获取 web 经典同步接口；并设为当前上下文
        return ContextHolder.currentWith(ctx.toContext(), () -> {
            try {
                Context ctx2 = Context.current();
                SaTokenContextSolonUtil.setContext(ctx2); //sa-token 新版需要（如果没有这个类，则乎略）

                //2.对接同步处理（使用 sa-token 接口）
                //new SaTokenFilter().doFilter(ctx2, ch->{});
                StpUtil.checkLogin();

                //3.检测是否要结束？
                if (ctx2.isHeadersSent()) {
                    ctx2.flush();
                    return false; //表示已经有输出（鉴权没通过），不必再继续
                } else {
                    return true;
                }
            } finally {
                SaTokenContextSolonUtil.clearContext(); //sa-token 新版需要
            }
        });
    }
}
```

执行结果说明：


| 结果           | 说明                                                            | 
| --------- | ------------------------------------ | 
| 返回 true    | 表示“继续”传递过滤                                        | 
| 返回 false   | 表示“不继续”。即触发 onComplete 结束处理      | 
| 抛出异常     | 表示异常。即触发 onError 结束处理                  | 



