Solon v3.2.1

网关的签权参考

</> markdown

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

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

1、简单鉴权参考(不涉及同步 io)

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

@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()

可以使用新接口 CloudGatewayFilterSyncExFilterSync(v3.2.1 后支持),简化开发。

具体对接参考:

@Component(index = -9) //index 为可选
public class CloudGatewayFilterImpl implements CloudGatewayFilterSync {
    /**
     * @return 是否继续
     * */
    @Override
    public boolean doFilterSync(ExContext ctx) throws Throwable {
        try {
            //1.获取 web 经典同步接口;并设为当前上下文
            Context ctx2 = ctx.toContext();
            ContextHolder.currentSet(ctx2);

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

            //3.检测是否要结束?
            if (ctx2.isHeadersSent()) {
                ctx2.flush();
                return false; //表示已经有输出(鉴权没通过),不必再继续
            } else {
                return true;
            }
        } finally {
            ContextHolder.currentRemove();
        }
    }
}

执行结果说明:

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