web-dev-qa-db-ja.com

Angular 5:プリフライトの応答に無効なHTTPステータスコード403があります

POSTリクエストをサーバーに送信すると、エラーが発生します:

Failed to load http://localhost:8181/test: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403.

バックエンドはJava Springで記述されています。テストを作成するための私の方法:

createTest() {
    const body = JSON.stringify({
      'description': 'grtogjoritjhio',
      'passingTime': 30,
      'title': 'hoijyhoit'
    });

    const httpOptions = {
      headers: new HttpHeaders({
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      )
    };

    return this._http.post(`${this._config.API_URLS.test}`, body, httpOptions)
      .subscribe(res => {
        console.log(res );
      }, error => {
        console.log(error);
    });
  }

Getメソッドは機能しますが、Postは機能しません。どちらもSwaggerとPostmanで動作します。 POSTメソッドを何度も変更しました。コードのヘッダーは機能しませんが、GoogleChromeに拡張する際の問題を解決しました。エラーのみが発生しました。

Response for preflight has invalid HTTP status code 403.

これはAngularの問題ではないようです。私または私の友人(バックエンドを作成した)がこの問題をどのように解決できるか教えてください。

3

問題:

Cross-Origin POSTリクエストの場合、ブラウザは最初にOPTIONS呼び出しを試行し、その呼び出しが成功した場合にのみ、実際のPOST呼び出しを実行します。ただし、あなたの場合、_'Access-Control-Allow-Origin'_応答ヘッダーがないため、OPTIONS呼び出しは失敗します。したがって、実際の呼び出しは行われません。

SLOUTION:

したがって、これを機能させるには、サーバー側でCORS構成を追加して、次のようなクロスオリジンリクエストに必要な適切なヘッダーを設定する必要があります。

  • response.setHeader("Access-Control-Allow-Credentials", "true");
  • response.setHeader("Access-Control-Allow-Headers", "content-type, if-none-match");
  • response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
  • response.setHeader("Access-Control-Allow-Origin", "*");
  • response.setHeader("Access-Control-Max-Age", "3600");

SpringがCORSリクエストを受け入れるようにする必要があります

また、Springセキュリティを適用し、APIなどに承認ヘッダーが必要な場合は、(アプリでCORSをサポートする必要がある場合のみ) Springセキュリティ構成の承認からOPTIONS呼び出しを除外する必要がありますファイル。

次のようになります。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {

  @Override
  public void configure(WebSecurity web) throws Exception {
    // Allow OPTIONS calls to be accessed without authentication
    web.ignoring()
        .antMatchers(HttpMethod.OPTIONS,"/**")

注意:

本番環境では、リバースプロキシ(nginxなど)を使用し、ブラウザがAPIを直接呼び出さないようにすることをお勧めします。その場合、上記のようにOPTIONS呼び出しを許可する必要はありません。

2
Ahmed Elkoussy

最近、Angular)でまったく同じ問題が発生しました。これは、PATCHDELETEOPTIONSなどの一部のリクエストがプリフライトリクエストをトリガーしているために発生します。 。これはWebブラウザのセキュリティ機能です。SwaggerとPostmanは、そのような機能を実装していないという理由だけで機能します。SpringでCORSリクエストを有効にするには、WebMvcConfigurerオブジェクトを返すBeanを作成する必要があります。このために追加のクラスを作成した場合に備えて、_@Configuration_を忘れてください。

_    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
                        .allowedHeaders("*");
            }
        };
    }
_

もちろん、これをニーズに合わせて調整することもできます。

1
Klimiuk S