事象
個人的にtypescript,Reactでフロントエンド、java,SpringでAPIサーバを作成しています。
1画面と1APIが完成したので、実際に画面からAPIを呼び出せるか確認しようとしたところ、以下ようなエラーが発生しました。
Access to XMLHttpRequest at 'http://localhost:8081/api/memo/register' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORSポリシーによってリクエストがブロックされました。
ヘッダに Access-Control-Allow-Originが含まれていません。
ということらしいです。
対応
CORSの設定がされていなかったので、サーバであるSpringBoot側でCORSの設定をおこなった。
package com.example.memo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class webConfig implements WebMvcConfigurer{
@Override
public void addCorsMappings(CorsRegistry registry){
// CORS設定を適用するリソース
registry.addMapping("/**")
// アクセスを許可するオリジン
.allowedOrigins("http://localhost:5173")
// アクセスを許可するHTTPメソッド
.allowedMethods("GET", "POST", "PUT", "DELETE")
// アクセスを許可するHTTPヘッダ
.allowedHeaders("*")
// Javascriptからの参照を許可するヘッダ
.exposedHeaders("Authorization")
// クッキーなどの認証情報の送信を許可するか
.allowCredentials(true)
// プリフライトリクエストの結果を保持する時間
.maxAge(3600);
}
}
CORS関連の備忘
オリジン
ウェブコンテンツにアクセスするためのURLに含まれるスキーマ、ホスト、ポートから定義されるもの
例)http://example.com:80
スキーマ→http
ホスト→example.com
ポート→80
同一オリジンポリシー
あるオリジンから取得したリソースは、同じオリジンのリソースしか取得できないことにするというルール
ブラウザに搭載されたセキュリティ上の制約
CORS(Cross Origin Resource Sharing)
オリジン間リソース共有のこと
同一オリジンポリシーによる制限を安全に緩和して、異なるオリジン間のリクエストを許可するための仕組み
プレフライトリクエスト
ブラウザからサーバへリクエストが送られる際に、GETなどの単純リクエストを除き、まずプレフライトリクエストという、サーバに対して「リクエスト送っていいですか?」という確認のリクエストをする。
リクエスト
・Optionsメソッド
・Access-Controll-Request-Headers:許可してほしいHTTPヘッダ
・Access-Controll-Request-Method:許可してほしいHTTPメソッド
・Origin:リクエスト送信者のオリジン
レスポンス
・Access-Controll-Allow-Origin:アクセスを許可するオリジン
・Access-Controll-Allow-Method:アクセスを許可するHTTPメソッド
・Access-Controll-Allow-Headers:アクセスを許可するHTTPヘッダ
・Access-Controll-Expose-Headers:Javascriptが参照を許可する
・Access-Controll-Allow-Credentials:認証情報を送信してよいか
成功すれば、200
失敗すれば、403 Forbidden