CORS 不允许 POST 请求

Posted

技术标签:

【中文标题】CORS 不允许 POST 请求【英文标题】:CORS does not allow POST requests 【发布时间】:2020-10-24 02:57:36 【问题描述】:

我正在开发一个全栈应用程序,但遇到了一个问题。

我尝试从我的 Angular 应用程序向 Spring Boot 后端应用程序执行 POST 请求,但每次由于 CORS 而失败。事实上,如果我将 POST 更改为 GET 请求,它总是会成功。

这是我的前端代码:

    finalizeRegister(userAccount: UserAccount) 
    return this._httpClient.post(`$Constants.apiRootaccount/finalize`, userAccount);
    

和拦截器:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
if (req.url.startsWith(Constants.apiRoot)) 
  return from(this._authService.getAccessToken().then(token => 
    const headers = new HttpHeaders().set('Authorization', `Bearer $token`);
    const authReq = req.clone( headers );
    return next.handle(authReq).pipe(tap(_ =>  , error => 
      var respError = error as HttpErrorResponse;
      if (respError && (respError.status === 401 || respError.status === 403)) 
        this._router.navigate(['/unauthorized']);
      
    )).toPromise();
  ));

else 
  return next.handle(req);

春季启动CORS配置:

 package pl.daniel.pawlowski.conquerorgame.security;

import com.auth0.spring.security.api.JwtWebSecurityConfigurer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.jwt.*;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

/**
 * Configures our application with Spring Security to restrict access to our API endpoints.
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Value( "$auth0.audience" )
    private String audience;

    @Value("$auth0.issuer")
    private String issuer;

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        JwtWebSecurityConfigurer
                .forRS256(audience, issuer)
                .configure(http)
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/api/public").permitAll()
                .antMatchers(HttpMethod.GET, "/api/private").authenticated()
                .antMatchers(HttpMethod.GET, "/api/admin/**").hasAuthority("view:admin")
                .anyRequest()
                .authenticated()
                .and()
                .cors();
    

    @Bean
    JwtDecoder jwtDecoder() 
        /*
        By default, Spring Security does not validate the "aud" claim of the token, to ensure that this token is
        indeed intended for our app. Adding our own validator is easy to do:
        */

        NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
                JwtDecoders.fromOidcIssuerLocation(issuer);

        OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(audience);
        OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuer);
        OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);

        jwtDecoder.setJwtValidator(withAudience);

        return jwtDecoder;
    

    @Bean
    CorsConfigurationSource corsConfigurationSource() 
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        configuration.setAllowedHeaders(Arrays.asList("Authorization"));
        return source;
    



我的配置似乎有问题,因为当我尝试使用 POST 请求调用任何端点时,在我的浏览器控制台中我看到:

访问 XMLHttpRequest 在 来自原点的“http://localhost:8081/api/account/finalize” “http://localhost:4200”已被 CORS 策略阻止:请求 标头字段内容类型不允许 预检响应中的 Access-Control-Allow-Headers。

【问题讨论】:

尝试使用 https 或在服务器端设置 cors 或尝试在客户端添加标头 该错误似乎表明 Spring 不喜欢您的 Angular 应用程序发送的 content-type 标头。也许有一种方法可以配置 Cors 以允许某些(或所有)HTTP 标头?貌似有:docs.spring.io/spring-framework/docs/current/javadoc-api/org/… 感谢@jrahhali,我已经设置:configuration.setAllowedHeaders(Arrays.asList("Authorization","content-type"));现在它可以工作了! 【参考方案1】:

您在不同的端口上运行。 您的前端由http://localhost:4200 提供服务,而您的后端则在http://localhost:8081 上运行。

由于您在不同的端口上运行,请求被解释为来自不同的来源。它们在同一台机器/主机名上并不重要,CORS 会阻止它,因为它是这样指定的。

禁用 CORS 或将 Access-Control-Allow-Origin-header 添加到您的 HTTP 响应中。

有关该主题的更多信息,请参阅https://enable-cors.org/

【讨论】:

以上是关于CORS 不允许 POST 请求的主要内容,如果未能解决你的问题,请参考以下文章

CORS POST 请求不起作用 - 选项(错误请求) - 不允许来源

CORS 策略中不允许请求方法 POST

Angular 7:发送 post 请求给出错误 405(不允许的方法)

不允许使用 CORS 使用 angularjs 进行跨域请求的 DELETE 请求

ZF2中的CORS POST请求变成OPTIONS请求

在 C# WebAPI 中,如何配置 CORS 以允许带有凭据和 json 内容的 POST 请求?