Reactjs 如何在Webflux、Spring Security、okta Spring boot starter和okta React中正确使用CORS?

Reactjs 如何在Webflux、Spring Security、okta Spring boot starter和okta React中正确使用CORS?,reactjs,axios,cors,spring-webflux,okta,Reactjs,Axios,Cors,Spring Webflux,Okta,我的webflux api中有一个CORS webFilter,当我通过邮递员对飞行前检查表提出选项请求时,我会得到一个带有正确标题的响应。但是,当我使用Axios和Okta React库从浏览器发出相同的请求来检索访问令牌时,会返回401 Unauthorized,并且不会返回我要查找的头。Axios是否在选项请求中不包括承载令牌?我是否需要白名单选项请求未经OKTA认证,OKTA不会处理吗 我使用的是邮递员中SPA的相同访问令牌。 我是否遗漏了Axios请求中的某些内容,是否需要使用Axio

我的webflux api中有一个CORS webFilter,当我通过邮递员对飞行前检查表提出选项请求时,我会得到一个带有正确标题的响应。但是,当我使用Axios和Okta React库从浏览器发出相同的请求来检索访问令牌时,会返回401 Unauthorized,并且不会返回我要查找的头。Axios是否在选项请求中不包括承载令牌?我是否需要白名单选项请求未经OKTA认证,OKTA不会处理吗

我使用的是邮递员中SPA的相同访问令牌。 我是否遗漏了Axios请求中的某些内容,是否需要使用Axios for CORS执行其他配置

我很困惑,为什么当邮递员发送选项请求时,webfilter会激活,而当在浏览器中从Axios调用时,webfilter不会激活

const getExperience=()=>{
const{accessToken}=authState;
axios({
方法:“获取”,
超时:10000,
标题:{
“授权”:`持有人${accessToken}`
},
网址:`http://localhost:8080/api/v1/professionals`
})。然后(响应=>{
setExperience(response.data);
});
}
import org.springframework.context.annotation.Bean;
导入org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
导入org.springframework.security.config.web.server.ServerHttpSecurity;
导入org.springframework.security.web.server.SecurityWebFilterChain;
@启用WebFluxSecurity
公共类安全配置{
@豆子
公共安全WebFilterChain安全WebFilterChain(ServerHttpSecurity http){
http
.授权交易所()
.anyExchange().authenticated()
.及()
.oauth2ResourceServer()
.jwt();
返回http.build();
}
}
import org.springframework.http.HttpHeaders;
导入org.springframework.http.HttpMethod;
导入org.springframework.http.HttpStatus;
导入org.springframework.http.server.reactive.ServerHttpResponse;
导入org.springframework.stereotype.Component;
导入org.springframework.web.server.ServerWebExchange;
导入org.springframework.web.server.WebFilter;
导入org.springframework.web.server.WebFilterChain;
导入reactor.core.publisher.Mono;
@组成部分
公共类CustomCorsWebFilter实现WebFilter{
允许的私有静态最终字符串\u HEADERS=“x-requested-with,authorization,Content Type,authorization,credential,x-XSRF-TOKEN”;
允许私有静态最终字符串\u METHODS=“GET、PUT、POST、DELETE、OPTIONS”;
允许的私有静态最终字符串\u ORIGIN=”http://localhost:3000";
私有静态最终字符串MAX_AGE=“3600”;
@凌驾
公共Mono筛选器(服务器WebExchange exchange、WebFilterChain链){
if(exchange.getRequest().getMethod()==HttpMethod.OPTIONS){
ServerHttpResponse response=exchange.getResponse();
HttpHeaders=response.getHeaders();
添加(“访问控制允许原点”,允许原点);
添加(“访问控制允许方法”,允许的方法);
添加(“访问控制最大年龄”,最大年龄);
添加(“访问控制允许标题”,允许的标题);
response.setStatusCode(HttpStatus.OK);
返回Mono.empty();
}
返回链。过滤器(交换);
}
}

以下是我用来设置CORS标题的内容

@Bean
CorsConfiguration源CorsConfiguration源(){
CorsConfiguration配置=新的CorsConfiguration();
配置.setAllowCredentials(true);
configuration.setAllowedOriginates(Collections.singletonList(“http://localhost:3000"));
setAllowedMethods(Collections.singletonList(“GET”);
configuration.setAllowedHeaders(Collections.singletonList(“*”));
UrlBasedCorsConfigurationSource=新的UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(“/**”,配置);
返回源;
}
我还使用了如下过滤器:

@Bean
CorsWebFilter CorsWebFilter(){
CorsConfiguration corsConfig=新的CorsConfiguration();
corsConfig.setAllowCredentials(真);
corsConfig.setAllowedOrigins(列表(“*”);
corsConfig.setMaxAge(3600升);
corsConfig.addAllowedMethod(“*”);
corsConfig.addAllowedHeader(“*”);
UrlBasedCorsConfigurationSource=新的UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(“/**”,corsConfig);
返回新的CorsWebFilter(源);
}

这很有效!那么,为什么这是可行的,而过滤器却不行呢?我认为最大的区别在于过滤器没有将allow credentials设置为true。我在我的答案中添加了一个过滤器示例。啊,这就解释了为什么我因为缺少授权头而得到未经授权的响应是不允许的。今天学到了新东西!只是为了澄清一下,在使用RESTController时,您是否仍然需要使用了上述配置选项之一的
@CrossOrigin
注释?否。以这种方式配置时,您不需要
@CrossOrigin