预检浏览器请求期间的 CORS 问题 [重复]
Posted
技术标签:
【中文标题】预检浏览器请求期间的 CORS 问题 [重复]【英文标题】:CORS Issue during preflight browser request [duplicate] 【发布时间】:2020-09-30 15:01:49 【问题描述】:在尝试通过 Angular 连接到我的 Rest API 时,我遇到了一个看似相当简单的 CORS 问题:
跨域请求被阻止:同源策略不允许读取位于http://mserverIP:port/apicontext/getsitebyuserid/userId 的远程资源。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。
我的 API 是在 Springboot 中设置的,我已经尝试过以下操作:
在类和方法级别设置 @CrossOrigin(origins = "*") 注释。还启用了跨源的 GET、POST、OPTIONS 以及所有标题。
使用以下代码全局设置添加的 CORS 配置:
httpServletResponse.setHeader("Access-Control-Allow-Origin","*");
httpServletResponse.setHeader("Access-Control-Allow-Methods","GET,POST,OPTIONS,HEAD");
httpServletResponse.setHeader("Access-Control-Max-Age", "7200");
httpServletResponse.setHeader("Access-Control-Allow-Headers",
"Content-Type, X-Requested-With, accept, authorization, Origin, Access-Control-Request-Method, Access-Control-Request-Headers");
尝试通过代理身份验证(使用的身份验证是 JWT)。
这条信息可能很重要:对于未经身份验证的 API,不会发生 CORS 问题,但对于受保护的路由,它会返回 403。即使我没有将身份验证标头设置为 true,受保护的路由也会出现问题。
另外,我之前注意到,在预检期间,它的 2 个标头组合会导致问题。如果我发送 origin:http://localhost:4200 和 Access-Control-Request-Method: GET 它会出错。但是,如果我发送其中一个标题,它就可以工作。在 OPTIONS 请求期间,如果有一个名为 origin 的请求头,则请求失败。如果我从邮递员那里删除来源,它会起作用。
【问题讨论】:
看起来你的 cross 工作不正常。试试这种方式***.com/a/59561352/8403689 @Imranmadbar- 这就像一个魅力。谢谢老哥!! 好吧@Charan 听起来不错,所以你可以在那里投赞成票。 【参考方案1】:首先,如果您使用的是 Spring Security,那么您可以摆脱类级别的注释并在您的安全配置类中全局处理 CORS 配置,例如:
@Override
protected void configure(HttpSecurity http) throws Exception
http.
cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/**").permitAll()
.antMatchers("/login").hasRole("ADMIN")
.antMatchers("/Signup").hasRole("USER")
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied")
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager(), customUserDetailService));
@Bean
public CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200")); //or * if you want to allow all
configuration.setAllowCredentials(true);
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
configuration.setExposedHeaders(Arrays.asList("custom-header1", "custom-header2"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
其次,您不需要 cors 过滤器手动将响应标头添加到每个请求,因为如果您正确配置 cors 配置,springboot 将通过 CorsFilter
自动添加所有必要的标头作为响应。因此,如果您使用带有弹簧安全性的 cors,那么使用提供的过滤器和您的配置会更容易。此外,请确保 springboot 自动配置对您有效,因为使用注释 @EnableWebMvc
将禁用自动配置,在这种情况下,您可能必须使用过滤器来处理 cors。
【讨论】:
正如我在第二点中提到的,我已经在全球范围内添加了 CORS 配置,但问题仍然存在。而且,如果使用这个: antMatchers("/**").permitAll();它只会覆盖所有系统的安全性。 @Charan 您可以根据需要配置弹簧安全性,我只是在示例代码中演示了一个简单的设置,只关注 cors 部分。 @Charan 如果您已经有 glabal 设置。尝试删除类级别配置、您添加的过滤器,并提供正确配置 cors bean 的全局配置,然后重试。另请分享您的全局配置以供分析。以上是关于预检浏览器请求期间的 CORS 问题 [重复]的主要内容,如果未能解决你的问题,请参考以下文章