はじめに:すべてが正しいはずなのに、なぜ?
はじめまして、学生エンジニアの@huyunokiです。
初めてのフロントエンド技術(Vue.js)とバックエンド(Spring Boot)を組み合わせたREST API開発。
「コードは完璧」「ロジックも通っている」。
それなのに、いざブラウザで動かそうとすると画面は真っ白。コンソールには無慈悲な赤字が並びます。
"Blocked by CORS policy: Response to preflight request doesn't pass access control check..."
今回は「フロントとバックの壁」であるCORSエラーを書いていきます。
そもそも、なぜCORSは「いかに大事」なのか?
結論から言うと、CORSはあなたのブラウザとデータを守る目的があるからです。
もしCORS(および同一オリジンポリシー)がなかったら?
あなたが悪意のあるサイト(A)を開いたとき、そのサイト上のスクリプトが、あなたのブラウザに保存されているクッキーを利用して、勝手に「銀行サイト(B)」や「SNS(C)」へリクエストを送り、個人情報を盗み取ることができてしまいます。
ブラウザには元々「同じオリジン(URLのセット)以外とは通信させない」という超強力な制限(同一オリジンポリシー)があります。
CORS(Cross-Origin Resource Sharing)は、この厳しい制限に対して、「このフロントエンド(Vue.js)からのアクセスなら安全だから許可していいよ!」とサーバー側から特別に許可を出す仕組みなのです。つまり、CORS設定を適切に行うことは、セキュリティを担保した上でアプリケーションを成立させるための必須工程です。
実録:Spring Boot 側での対策とハマりポイント
Spring BootでCORSエラーを解消しようとする際、単に「おまじない」として設定するだけでは解決しない罠がいくつかあります。
1. @CrossOrigin の付与だけでは足りない場合
コントローラーに @CrossOrigin をつければOKと思われがちですが、以下の点に注意が必要です。
-
許可するメソッドの指定: デフォルトでは基本的なものしか許可されません。
PUTやDELETEを使う場合は明示が必要です。@CrossOrigin(origins = "http://localhost:8080", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}) -
グローバル設定の検討: 全てのコントローラーに書くのは非効率です。
WebMvcConfigurerを実装して一括設定するのがスマートです。
2. 「サーバー再起動」の忘却
Java/Spring Boot 開発で意外と多いのがこれです。
設定を書き換えても、サーバーを再起動しなければバイナリに反映されません。「設定したはずなのに直らない!」と1時間悩んだ原因が「再起動していなかっただけ」というのは、エンジニアあるあるの悲劇です。
3. プリフライト(Preflight)リクエスト
ブラウザは複雑なリクエストを送る前に、一度「この通信していい?」とサーバーにお伺い(OPTIONSメソッド)を立てます。サーバー側でこの OPTIONS を適切にハンドリングできていないと、本体の処理が正しくてもCORSエラーで落とされます。
まとめ:CORSはエラーではなく「対話」である
CORSエラーが出たとき、それはブラウザが「知らないやつが勝手に通信しようとしてるけど、本当に大丈夫?」とあなたに警告してくれている証拠です。
- フロントのURLが正しいか?
- 許可するメソッド(GET/POSTなど)は足りているか?
- サーバーは最新の設定で動いているか?
これらを一つずつ確認することが、REST開発における一歩目になります。二度と同じミスで真っ白な画面と向き合わないよう、この「心の壁」の壊し方を胸に刻んでおきましょう。
「CORSを忘れるな。」