【问题标题】:CORS does not allow POST requestsCORS 不允许 POST 请求
【发布时间】:2023-03-10 11:30:01
【问题描述】:

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

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

这是我的前端代码:

    finalizeRegister(userAccount: UserAccount) {
    return this._httpClient.post(`${Constants.apiRoot}account/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"));现在它可以工作了!

标签: java angular rest jwt


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2019-01-04
    • 2018-07-28
    • 1970-01-01
    • 2017-03-15
    • 2013-07-16
    • 2015-03-09
    • 2016-09-15
    • 2019-07-02
    • 2016-11-18
    相关资源
    最近更新 更多