摘自:https://coding.imooc.com/learn/questiondetail/142262.html

想要通过gateway实现拦截器,只需要拦截backend-center和search-center这两个服务,但是目前发现一个情况,如果backend-center和search-center这两个服务没启动,拦截器会生效,如果启动,不会进入拦截器

图片描述

代码如下:

@Slf4j
@Component
public class AuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthorizeGatewayFilterFactory.Config> {

    private static final String AUTHORIZE_TOKEN = "X-Token";
    private static final String SEARCH_CENTER = "search-center";
    private static final String SEARCH_CENTER_PASS_API = "rent/house/autocomplete";

    public AuthorizeGatewayFilterFactory() {
        super(Config.class);
        log.info("Loaded GatewayFilterFactory [Authorize]");
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("enabled");
    }

    /**
     * MethodName: apply
     * Description: 对backend-center的API请求cookie中必须包含X-Token
     * 对search-center的rent/house/autocomplete请求包含X-Token可以通过,其余任何请求直接返回401
     * Param: [config]
     * Author: liguohui
     * Date: 14:04 2019/9/14
    **/
    @Override
    public GatewayFilter apply(AuthorizeGatewayFilterFactory.Config config) {
        return (exchange, chain) -> {
            log.info("过滤器工厂生效,请求进入");
            if (!config.isEnabled()) {
                return chain.filter(exchange);
            }

            ServerHttpRequest request = exchange.getRequest();

            ServerHttpResponse response = exchange.getResponse();

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", HttpStatus.UNAUTHORIZED.value());
            jsonObject.put("message", "请求非法,请登录后再访问");
            byte[] data = jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8);

            URI uri = request.getURI();
            log.info("URL信息: {}", uri.toString());
            //search-center除了rent/house/autocomplete,其他的api不允许直接请求,只是用于微服务之间调用
            if (uri.toString().contains(SEARCH_CENTER) && !uri.toString().contains(SEARCH_CENTER_PASS_API)) {
                log.warn("请求服务为:{},不允许直接访问API", SEARCH_CENTER);
                jsonObject.put("message", "请求非法,不允许直接访问");
                byte[] data1 = jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8);

                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                DataBuffer buffer = response.bufferFactory().wrap(data1);
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                return response.writeWith(Mono.just(buffer));
            }

            MultiValueMap<String, HttpCookie> map = request.getCookies();
            List<HttpCookie> list = map.get(AUTHORIZE_TOKEN);

            String token = "";
            if (list != null) {
                for (HttpCookie cookie : list) {
                    if (StringUtils.equals(AUTHORIZE_TOKEN, cookie.getName())) {
                        token = cookie.getValue();
                        break;
                    }
                }
            }

            if (list == null || StringUtils.isEmpty(token)) {
                log.warn("没有token信息,请求非法");
                response.setStatusCode(HttpStatus.UNAUTHORIZED);

                DataBuffer buffer = response.bufferFactory().wrap(data);
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                return response.writeWith(Mono.just(buffer));
            }

            log.info("请求校验通过,继续请求具体微服务API");
            return chain.filter(exchange);
        };
    }

    public static class Config {
        // 控制是否开启认证
        private boolean enabled;

        public Config() {}

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    }
}

所以,现在有点懵逼,不知道这个AbstractGatewayFilterFactory为什么会这样?

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐