【Spring Boot】CORSの設定
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-Credentials | Cookie などの資格情報を含むリクエストを許可するかを真偽値(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: AuthorizationCORS の設定
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: *デフォルトの設定では、すべてのオリジンからのリクエストが許可されてしまうため注意してください。 設定を変更するには、以下のプロパティを使用します。
| プロパティ | 説明 |
|---|---|
origins | Access-Control-Allow-Originの設定 |
exposedHeaders | Access-Control-Expose-Headersの設定 |
maxAge | Access-Control-Max-Ageの設定 |
allowCredentials | Access-Control-Allow-Credentialsの設定 |
methods | Access-Control-Allow-Methodsの設定 |
allowedHeaders | Access-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);
}
}設定に使用するクラスがCorsRegisterとCorsConfigurationとで違いますが、設定する内容自体に変わりはありません。
どちらも問題なく動作します。