web-dev-qa-db-ja.com

Spring 5 WebfluxでCORSを有効にしますか?

Spring 5 Webfluxプロジェクトで[〜#〜] cors [〜#〜]を有効にする方法

適切なドキュメントが見つかりません。

17
Dachstein

Webflux Configurerを使用した別のソリューションを次に示します。

サイドノート:(プロジェクトからコピーされた)Kotlinコードですが、これをJava Code。

@Configuration
@EnableWebFlux
class WebConfig: WebFluxConfigurer
{
    override fun addCorsMappings(registry: CorsRegistry)
    {
        registry.addMapping("/**")
            .allowedOrigins("*") // any Host or put domain(s) here
            .allowedMethods("GET, POST") // put the http verbs you want allow
            .allowedHeaders("Authorization") // put the http headers you want allow
    }
}
7
Dachstein

このカスタムフィルターで成功しました。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;

import reactor.core.publisher.Mono;


@Configuration
public class CorsConfiguration {

  private static final String ALLOWED_HEADERS = "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN";
  private static final String ALLOWED_METHODS = "GET, PUT, POST, DELETE, OPTIONS";
  private static final String ALLOWED_Origin = "*";
  private static final String MAX_AGE = "3600";

  @Bean
  public WebFilter corsFilter() {
    return (ServerWebExchange ctx, WebFilterChain chain) -> {
      ServerHttpRequest request = ctx.getRequest();
      if (CorsUtils.isCorsRequest(request)) {
        ServerHttpResponse response = ctx.getResponse();
        HttpHeaders headers = response.getHeaders();
        headers.add("Access-Control-Allow-Origin", ALLOWED_Origin);
        headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
        headers.add("Access-Control-Max-Age", MAX_AGE);
        headers.add("Access-Control-Allow-Headers",ALLOWED_HEADERS);
        if (request.getMethod() == HttpMethod.OPTIONS) {
          response.setStatusCode(HttpStatus.OK);
          return Mono.empty();
        }
      }
      return chain.filter(ctx);
    };
  }

}

およびorg.springframework.boot:spring-boot-starter-webを依存関係として含めるべきではありません-フィルタはそれと連動しません。

26
@Configuration
public class WebFluxConfig {

    @Bean
    public WebFluxConfigurer corsConfigurer() {
        return new WebFluxConfigurerComposite() {

            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("*")
                        .allowedMethods("*");
            }
        };
    }
}

以下に対応します:

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {

        @Override
        public void addCorsMappings(CorsRegistry registry) {

春のMVC用。

8
milbr

@Dachsteinのおかげで、WebMvc構成をWebfluxに置き換えることが、ここでグローバルCORS構成を追加する正しい方法です。

@Configuration
@EnableWebFlux
public class CORSConfig implements WebFluxConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("*");
    }
}
1

KotlinのSAM変換がどのように機能するかをさらに理解することなく、誰かがZufarの答えのKotlinバージョン(webfluxルーティング機能を備えたチャームのように機能する)を望んでいる場合、コードは次のとおりです。

@Bean
fun corsFilter(): WebFilter {
    return WebFilter { ctx, chain ->
        val request = ctx.request
        if (CorsUtils.isCorsRequest(request)) {
            val response = ctx.response
            val headers = response.headers
            headers.add("Access-Control-Allow-Origin", ALLOWED_Origin)
            headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS)
            headers.add("Access-Control-Max-Age", MAX_AGE)
            headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS)
            if (request.method === HttpMethod.OPTIONS) {
                response.statusCode = HttpStatus.OK
                return@WebFilter Mono.empty<Void>()
            }
        }
        chain.filter(ctx)
    }
}

[〜#〜] update [〜#〜]それをテストし始めたとき、この解決策に1つの問題が見つかりました。 Okすべてのメソッドを本当に許可したい場合。しかし、たとえばPOSTOPTIONSのみを許可したい場合。ブラウザはPUTを送信しようとしています。

その後、プリフライトレスポンスは、基本的に「おい、私はPOSTとOPTIONSしか提供できませんが、Access-Control-Request-Method=PUTでリクエストを出すと、HTTPステータスはOKになります。ただし、403 Forbiddenのように、Access-Control-Allow-Methodsなどのヘッダーのほとんどは、すべてのCORSリクエストではなく、プリフライトリクエストにのみ追加する必要があります。

@Bean
fun corsWebFilter(): CorsWebFilter {
    val corsConfig = CorsConfiguration()
    corsConfig.allowedOrigins = Arrays.asList(ALLOWED_ORIGINS)
    corsConfig.maxAge = MAX_AGE.toLong()
    //Notice it's singular. Can't be comma separated list
    corsConfig.addAllowedMethod(ALLOWED_METHOD)
    corsConfig.addAllowedHeader(ALLOWED_HEADER)

    val source = UrlBasedCorsConfigurationSource()
    source.registerCorsConfiguration(MATCH_ALL_PATH_SEGMENTS, corsConfig)

    return CorsWebFilter(source)
}

どこで

const val MATCH_ALL_PATH_SEGMENTS = "/**"
0
yuranos87

公式ドキュメントへのリンクはこちら

https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-cors

3つの主なオプションがあります

1)レストコントローラーで@CrossOriginアノテーションを使用する-クラスレベルやメソッドレベルで使用可能

2)WebFluxConfigurerからaddCorsMappingメソッドを実装します-グローバルCorsRegistryオブジェクトへのフックを提供します

3)CorsWebFilterコンポーネントを定義する-機能的なエンドポイントに最適

ドキュメントを見てください、よく説明されています。

個人的には、開発中にcorsを許可したいときに3番目のオプションを使用し、フロントエンドモジュールからバックエンドを切り離しました。

フロントエンドで反応またはangularアプリを使用している間に、バックエンドモジュールでwebfluxを使用していることを想像してください。 nettyでバックエンドを実行すると、ポートが異なり、これによりCORSの問題が発生します。3番目のオプションを使用すると、@ Componentを@Profile( "dev")に簡単にリンクできます。

0
gtuz