Spring 5 Webfluxプロジェクトで[〜#〜] cors [〜#〜]を有効にする方法
適切なドキュメントが見つかりません。
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
}
}
このカスタムフィルターで成功しました。
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
を依存関係として含めるべきではありません-フィルタはそれと連動しません。
@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用。
@Dachsteinのおかげで、WebMvc構成をWebfluxに置き換えることが、ここでグローバルCORS構成を追加する正しい方法です。
@Configuration
@EnableWebFlux
public class CORSConfig implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*");
}
}
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すべてのメソッドを本当に許可したい場合。しかし、たとえばPOST
とOPTIONS
のみを許可したい場合。ブラウザは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 = "/**"
公式ドキュメントへのリンクはこちら
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")に簡単にリンクできます。