spring.svg

【Spring Boot】CORSの設定

SpringBoot
2024/03/09

CORS とは

CORS の基礎

CORS は、Cross-Origin Resource Sharing の略で、ブラウザが別のオリジンに対して JavaScript によるリクエストを送信した場合に、 そのリクエストをブロックするかどうかを設定するためのものです。

オリジンとは、プロトコル、ホスト、ポートの組み合わせのことで、どれか 1 つでも違う場合は別のオリジンとなります。 つまり、http://localhost:8080の API に対して、http://localhost:3000のページからリクエストを送信することは、CORS の対象になります。

CORS の設定は、API 側で行います。

プリフライトリクエスト

ブラウザ(クライアント)は別のオリジンにリクエストを送信する前に、本当にリクエストを送信していいかの情報を得るためのリクエストを送信します。 これをプリフライトリクエストといいます。

プリフライトリクエストは OPTIONS メソッドで送信し、レスポンスヘッダーに設定された CORS の情報を参照することで、本来送信するはずだったリクエストを送信するかを判断します。 これは特にユーザーが意識しなくても、ブラウザが自動で送信して判断してくれます。

レスポンスヘッダー

プリフライトリクエストのレスポンスヘッダーには以下のものがあります。 API は、これによって別のオリジンからのリクエストをブロックするかを設定することになります。

レスポンスヘッダー説明
Access-Control-Allow-Originリクエストを許可するオリジンを設定
すべてのオリジンを許可する場合は*を設定
Access-Control-Expose-Headersレスポンス情報として公開するヘッダーを設定
すべて公開する場合は*を設定
Access-Control-Max-Ageプリフライトリクエストの結果をキャッシュしてよい時間を設定
Access-Control-Allow-CredentialsCookie などの資格情報を含むリクエストを許可するかを真偽値(true/false)で設定
Access-Control-Allow-Methodsリクエスト可能な HTTP メソッドを設定
すべて許可する場合は*を設定
Access-Control-Allow-Headersリクエスト可能な HTTP ヘッダーを設定
すべて許可する場合は*を設定

例えば以下のように設定されます。

Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization

CORS の設定

Spring Boot で CORS を設定するには、以下の 2 つの方法があります。

@CrossOrigin

@CrossOriginは、CORS の設定のためのアノテーションで、コントローラークラスに付与します。

@RestController
@RequestMapping('/api/sample')
@CrossOrigin
public class SampleController {
  //...
}

これにより、コントローラーで定義したすべてのリクエストに対して CORS の設定が適用されます。 リクエスト別に設定したい場合は、コントローラーではなくメソッドに付与します。

@CrossOriginによって、プリフライトリクエストのレスポンスヘッダーは以下のように設定されます。 (実際に送信される内容とは異なります。)

Access-Control-Allow-Origin: *
Access-Control-Max-Age: 1800
Access-Control-Credentials: false
Access-Control-Allow-Methods: コントローラーで設定したメソッドすべて
Access-Control-Allow-Headers: *

デフォルトの設定では、すべてのオリジンからのリクエストが許可されてしまうため注意してください。 設定を変更するには、以下のプロパティを使用します。

プロパティ説明
originsAccess-Control-Allow-Originの設定
exposedHeadersAccess-Control-Expose-Headersの設定
maxAgeAccess-Control-Max-Ageの設定
allowCredentialsAccess-Control-Allow-Credentialsの設定
methodsAccess-Control-Allow-Methodsの設定
allowedHeadersAccess-Control-Allow-Headersの設定
@RestController
@RequestMapping('/api/sample')
@CrossOrigin(origins = "http://localhost:3000")
public class SampleController {
  //...
}

WebMvcConfigure

すべてのリクエストに対して CORS を設定したい場合は、WebMvcConfigurerを使用します。 WebMvcConfigurerには、CORS の設定用にaddCorsMappings()とメソッドが定義されているため、これを実装します。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
            .allowedOrigins("http://localhost:3000")
            .allowedMethods("GET", "POST", "PUT", "DELETE")
            .allowedHeaders("Authorization");
  }
}

addMappingで CORS の対象となるパスを設定し、その後にレスポンスヘッダーの設定を行います。 レスポンスヘッダーの設定は以下のメソッドによって行います。

  • allowedOrigins(String... origins)
  • exposedHeaders(String... headers)
  • maxAge(long maxAge)
  • allowCredentials(boolean allowCredentials)
  • allowedMethods(String... methods)
  • allowedHeaders(String... headers)

CorsFilter

上記のaddCorsMappings()の実装の他に、以下のように組み込みのCorsFilterを使用する方法があります。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Bean
    CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("http://localhost:3000");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);

        return new CorsFilter(source);
    }
}

設定に使用するクラスがCorsRegisterCorsConfigurationとで違いますが、設定する内容自体に変わりはありません。 どちらも問題なく動作します。