请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

通过AbstractGatewayFilterFactory实现拦截器

想要通过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为什么会这样?

正在回答 回答被采纳积分+3

2回答

慕九州9401200 2020-09-30 15:40:04

怎么解决的呢,我也遇到了

0 回复 有任何疑惑可以回复我~
  • 大目 #1
    http://coding.imooc.com/learn/questiondetail/142334.html
    回复 有任何疑惑可以回复我~ 2020-10-09 15:22:04
提问者 小屁孩丶 2019-09-14 20:20:50

原因找到了。。。

0 回复 有任何疑惑可以回复我~
  • 大目 #1
    不好意思,刚到家。解决就好哈……
    PS. 服务名称尽量不要使用下划线 例如:lb://backend_center。
    lb后面的这玩意儿,是Ribbon的世界里叫虚拟主机名,而对于虚拟主机名,下划线是不允许的。
    回复 有任何疑惑可以回复我~ 2019-09-14 21:35:45
  • 提问者 小屁孩丶 回复 大目 #2
    我测试了一下,当把backend_center启动的时候。只有gateway.discovery.locator.enabled=true配置去掉,自定义的AbstractGatewayFilterFactory才会生效,可是去掉了,我的服务没法正常通过gateway进行跳转了,这要怎么处理呢?
    这种情况下,难道只能通过配置url去对应服务,而不能自动通过nacos发现服务吗?
    回复 有任何疑惑可以回复我~ 2019-09-15 09:34:08
  • 大目 回复 提问者 小屁孩丶 #3
    您好,在这里回复啦:http://coding.imooc.com/learn/questiondetail/142334.html
    回复 有任何疑惑可以回复我~ 2019-09-15 17:06:55
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号