はじめに
こんにちは、エンジニアのkeitaMaxです。
npm run dev
で起動しているNext.jsから、Dockerで起動しているLaravel1のAPIを叩いたらCORSエラーが出て困った話です。
バージョン
Laravel Framework 11.2.0
next 14.2.3
困ったこと
Dockerのnginxで以下のように設定しているのでCORS回避できていると思っていたのですが、実際にNext.jsからAPIを叩いたところ、CORSエラーが出てしまいました。
location / {
try_files $uri $uri/ /index.php?$query_string;
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
add_header Access-Control-Allow-Credentials true;
}
CORSとは
オリジン間リソース共有 (Cross-Origin Resource Sharing, CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。ウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、オリジン間 HTTP リクエストを実行します。
セキュリティ上の理由から、ブラウザーは、スクリプトによって開始されるオリジン間 HTTP リクエストを制限しています。例えば、 XMLHttpRequestや Fetch API は同一オリジンポリシー (same-origin policy) に従います。つまり、これらの API を使用するウェブアプリケーションは、そのアプリケーションが読み込まれたのと同じオリジンに対してのみリソースのリクエストを行うことができ、それ以外のオリジンからの場合は正しい CORS ヘッダーを含んでいることが必要です。
(引用;https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)
セキュリティ上の理由で、ドメインが違うものからのJSのリクエストをブラウザがブロックするらしいです。
結論
参考した記事(下に記載)によると、Laravelの方のconfig/cors.php
を設定すれば解決できるそうです。
記事の通りにconfig/cors.php
を作成し、以下のようにしました。
以下コマンドを実行し、config/cors.php
を作成しました。
php artisan config:publish cors
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
これを記載し、Next.jsからAPIを叩くと無事問題なく叩くことができました。
各設定項目については参考元URLの方で解説されていたのでみてみてください。
参考
もう少し
このままだとセキュリティ的に良くないので、今回はローカルのもののみを許可しようと思っているので、以下のように修正しました。
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:6006','http://localhost:3000'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
おわりに
CORSについての理解も足りなかったなと思います。
この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。
最後まで読んでいただきありがとうございました!