Heim  >  Artikel  >  Java  >  Zuul implementiert Cors domänenübergreifend auf zwei Arten: corsFilter und erbender ZuulFilter

Zuul implementiert Cors domänenübergreifend auf zwei Arten: corsFilter und erbender ZuulFilter

php是最好的语言
php是最好的语言Original
2018-08-03 14:40:3911206Durchsuche

Jeder weiß, dass Spring Boot über @CrossOrigin domänenübergreifend arbeiten kann. Wenn Sie jedoch in Spring Cloud eine domänenübergreifende Steuerung mit einer so feinen Granularität durchführen möchten, ist dies zu umständlich. Daher wird es im Allgemeinen im Routing-Zuul implementiert.

Der erste Weg: corsFilter

Fügen Sie einen corsFilter unter dem Zuul-Dienst hinzu, um eine domänenübergreifende Wirkung zu erzielen, die einfach zu implementieren ist. Der Code lautet wie folgt:

@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;
    }
}

Nach dem Testen ist diese Konfiguration im Fall von http domänenübergreifend in Ordnung, aber wenn meine Umgebung auf https umstellt, treten seltsame Probleme auf. Erklären Sie das Problem, auf das ich gestoßen bin.
Front-EndDienst A und Back-End-Dienst B befinden sich auf demselben Server, wenn Dienst A Dienst B aufruft , Wenn Dienst A über Lastausgleich in Dienst B eintritt: Wenn
http verwendet wird, ist die Anforderung von Dienst A domänenübergreifend erfolgreich; verwendet, Dienst ADie Anfrage ist domänenübergreifend fehlgeschlagen.
Das heißt, wenn der Port 443 ist, wird dies als domänenübergreifender Fehler betrachtet! !
Ich habe zuerst die Anforderungsheader verglichen und dachte, dass der „X-forwared-port, X-forwarded-host“ von ExposedHeader fehlte, aber nachdem ich ihn hinzugefügt hatte, schlug er immer noch fehl. Da ich es eilig hatte, online zu gehen, habe ich nicht ausführlich getestet, was dazu führte, dass die https-Anfrage domänenübergreifend fehlschlug. (Wenn Sie also feststellen, dass an dem, was ich geschrieben habe, etwas nicht stimmt, informieren Sie mich bitte unbedingt und lassen Sie mich verstehen, warum es fehlgeschlagen ist! Vielen Dank!)

Zweiter Weg: ZuulFilter erben

Weil des ersten Weges Nachdem ich unter https gescheitert bin, habe ich versucht, zuulfilter zu verwenden, um cors zu implementieren

Es werden insgesamt zwei Filter benötigt: ein Pre-Filter, ein Post-Filter

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;
    }
}

Vorfilter wird verwendet, um OPTIONS-Anfragen vorzuverarbeiten. Wenn festgestellt wird, dass es sich um eine OPTIONS-Anfrage handelt, wird ein domänenübergreifender Antwortheader angegeben, der nicht von zuul weitergeleitet wird und direkt den Erfolg zurückgibt (. 200), was den domänenübergreifenden Zugriff auf den Front-End-Dienst ermöglicht


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-Filter wird verwendet, um andere Anfragen als die Vorverarbeitung zu verarbeiten. OPTIONS Für normale Anfragen: Es müssen nicht nur domänenübergreifende Anforderungsheader angegeben werden, sondern die Anforderung muss auch weitergeleitet werden können (andernfalls endet Ihre Anforderung hier) und dann wird der Statuscode 200 zurückgegeben. (emmmm... ich denke, ich muss vielleicht darüber nachdenken, ob ich hier 200 zurückgeben soll...)

Wenn es auf die oben beschriebene Weise konfiguriert wird, werden die Probleme, die in der Methode auftreten, gelöst. Service A kann Service B normal anfordern

Obwohl die Anforderungen normal erfüllt wurden, habe ich immer noch das Gefühl, dass es viele Zweifel gibt. Ich hoffe, dass Sie mich auf die Mängel hinweisen können, wenn Sie es sehen. Lassen Sie uns gemeinsam darüber diskutieren!

Verwandte Artikel:

Domänenübergreifende Lösung eins: Verwenden Sie CORS, um domänenübergreifendes_html/css_WEB-ITnose zu implementieren

Verwenden Sie CORS, um Implementieren Sie die domänenübergreifende WebApi Ajax-Anforderungsmethode

Das obige ist der detaillierte Inhalt vonZuul implementiert Cors domänenübergreifend auf zwei Arten: corsFilter und erbender ZuulFilter. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn