Zuul は、corsFilter と ZuulFilter の継承の 2 つの方法で Cors クロスドメインを実装します。

php是最好的语言
リリース: 2018-08-03 14:40:39
オリジナル
11217 人が閲覧しました

Spring Boot が @CrossOrigin を通じてクロスドメインを実現できることは誰もが知っています。ただ、Spring Cloudではそこまで細かい粒度でクロスドメインを制御したい場合は面倒なので、一般的にはrouting zuulで実装することになります。

最初の方法: corsFilter

zuul サービスの下に corsFilter を追加して、クロスドメインを実現します。これは実装が簡単です。コードは次のとおりです

@Configuration
public class GateWayCorsConfig {
   @Bean
    public FilterRegistrationBean corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        //这个请求头在https中会出现,但是有点问题,下面我会说
        //config.addExposedHeader("X-forwared-port, X-forwarded-host"); 
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}
ログイン後にコピー

テストした結果、http の場合、この構成はドメイン間で問題ありませんが、私の環境が https に切り替わると、奇妙な問題が発生します。私が遭遇した問題を説明してください。
フロントエンドサービスAバックエンドサービスBが同じサーバー上にある場合、サービスAサービスBを呼び出すと、サービスAは負荷分散を通じてサービスBに入ります。
service Aのクロスドメインリクエストは成功しますが、httpsを使用するとservice Aのクロスドメインリクエストは失敗します。
つまり、ポートが 443 の場合、クロスドメイン障害とみなされます。 ! 最初リクエストヘッダーを比較したところ、ExusedHeaderの「X-forwared-port、X-forwarded-host」が抜けているのかと思いましたが、追加してもやはり失敗しました。オンラインに接続することを急いでいたため、https リクエストがクロスドメインで失敗する原因について詳細なテストは実施しませんでした。 (したがって、私が書いたことに何か間違っていることに気づいた場合は、必ず私に通知して、失敗した理由を理解させてください! ありがとう!)

2 番目の方法: ZuulFilter を継承する

最初の方法は https で失敗したため、 zuulfilter

を使用してcorsを実装する方法には、pre、postの合計2つのフィルタが必要です


Pre-Filter:

@Component
public class FirstFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(FirstFilter.class);

    @Override
    public String filterType() {
        /*
        pre:可以在请求被路由之前调用
        route:在路由请求时候被调用
        post:在route和error过滤器之后被调用
        error:处理请求时发生错误时被调用
        * */
        // 前置过滤器
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        //// 优先级为0,数字越大,优先级越低
        return 0;
    }
    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        //只过滤OPTIONS 请求
        if(request.getMethod().equals(RequestMethod.OPTIONS.name())){
            return true;
        }

        return false;
    }

    @Override
    public Object run() {
        logger.debug("*****************FirstFilter run start*****************");
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse response = ctx.getResponse();
        HttpServletRequest request = ctx.getRequest();
        response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials","true");
        response.setHeader("Access-Control-Allow-Headers","authorization, content-type");
        response.setHeader("Access-Control-Allow-Methods","POST,GET");
        response.setHeader("Access-Control-Expose-Headers","X-forwared-port, X-forwarded-host");
        response.setHeader("Vary","Origin,Access-Control-Request-Method,Access-Control-Request-Headers");
        //不再路由
        ctx.setSendZuulResponse(false);
        ctx.setResponseStatusCode(200);
        logger.debug("*****************FirstFilter run end*****************");
        return null;
    }
}
ログイン後にコピー

Pre-Filterは、前処理OPTIONSリクエストを処理するために使用されます。 OPTIONS リクエスト、Output にクロスドメイン応答ヘッダーを与え、それに対して zuul ルーティングを実行せず、直接成功 (200) を返し、フロントエンド サービスのクロスドメイン


post-Filter:

@Component
public class PostFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(PostFilter.class);

    @Override
    public String filterType() {
        /*
        pre:可以在请求被路由之前调用
        route:在路由请求时候被调用
        post:在route和error过滤器之后被调用
        error:处理请求时发生错误时被调用
        * */
        // 前置过滤器
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        //// 优先级为0,数字越大,优先级越低
        return 2;
    }
    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        //过滤各种POST请求
        if(request.getMethod().equals(RequestMethod.OPTIONS.name())){
            return false;
        }
        return true;
    }

    @Override
    public Object run() {
        logger.debug("*****************PostFilter run start*****************");
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse response = ctx.getResponse();
        HttpServletRequest request = ctx.getRequest();
        response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials","true");
        response.setHeader("Access-Control-Expose-Headers","X-forwared-port, X-forwarded-host");
        response.setHeader("Vary","Origin,Access-Control-Request-Method,Access-Control-Request-Headers");
        //允许继续路由
        ctx.setSendZuulResponse(true);
        ctx.setResponseStatusCode(200);
        logger.debug("*****************PostFilter run end*****************");
        return null;
    }
}
ログイン後にコピー
Post -フィルターは、前処理オプション以外のリクエストを処理するために使用されます。通常のリクエストは、クロスドメインリクエストヘッダーを提供するだけでなく、リクエストのルーティングも許可する必要があり (そうしないと、リクエストはここで終了します)、ステータスコード 200 を返します。 。 (うーん...ここで200を返すか考えないといけないかも...)

上記のように設定すれば、メソッド内で発生する問題は解決されます。サービスAはサービスBを正常にリクエストできます

要件は正常​​に満たしていますが、まだ疑問点が多いと感じていますので、ご覧になった方は欠点を指摘していただければと思います。一緒に議論してください!

関連記事:

クロスドメイン ソリューション 1: CORS を使用して Cross-domain_html/css_WEB-ITnose を実装する

CORS を使用して WebApi Ajax クロスドメイン リクエストを実装する方法

以上がZuul は、corsFilter と ZuulFilter の継承の 2 つの方法で Cors クロスドメインを実装します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート