CORS設定について

参考記事
不具合発生手順
前提条件
Frontend:React
Backend:NestJS
・NestJSで作成したAPIをReactから叩いている。
エラー
以下のようなエラーが発生する
Access to fetch at 'http://localhost:3000/item' from origin 'http://localhost:4000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
原因
localhost:3000からlocalhost:4000へのリクエストはCORSポリシーによりブロックされている
CORSポリシーとは
CORS(Cross-Origin Resource Sharing)とは、異なるオリジン間でリソースを共有するための仕組みです。具体的には、ウェブページが自分のオリジンとは異なるドメインからリソース(画像、スクリプト、スタイルシートなど)を安全にリクエストできるようにするためのHTTPヘッダーを使用します。
CORSの基本概念
同一オリジンポリシー: CORSの背景には、同一オリジンポリシーがあります。これは、ウェブページが自分が読み込まれたオリジン(スキーム、ホスト、ポートが同じ)以外のリソースにアクセスすることを制限するセキュリティ機能です。このポリシーは、悪意のあるスクリプトが他のドメインのデータにアクセスするのを防ぐために設けられています。
CORSの仕組み: CORSは、サーバーが特定のオリジンからのリクエストを許可するために、HTTPレスポンスヘッダーを使用します。これにより、ブラウザはリクエストが許可されているかどうかを判断します。例えば、Access-Control-Allow-Originヘッダーを使用して、どのオリジンがリソースにアクセスできるかを指定します。
CORSの重要性
CORSは、以下のような理由から重要です:
セキュリティの向上: CORSを使用することで、ウェブアプリケーションは他のオリジンからのリソースを安全に利用できるようになります。これにより、開発者はより柔軟で強力なアプリケーションを構築できます。
リソースの共有: CORSを利用することで、異なるドメイン間でのデータやリソースの共有が可能になります。これにより、例えば、外部APIからデータを取得したり、他のドメインの画像やスクリプトを埋め込むことができます。
CORSの設定とベストプラクティス
CORSを適切に設定することは非常に重要です。以下は、CORSを安全に実装するためのベストプラクティスです:
明示的なオリジンの指定: ワイルドカード(*)を使用するのではなく、許可するオリジンを明示的に指定することが推奨されます。これにより、悪意のあるサイトからのアクセスを防ぐことができます。
HTTPメソッドとヘッダーの制限: Access-Control-Allow-MethodsやAccess-Control-Allow-Headersを使用して、許可するHTTPメソッドやカスタムヘッダーを明示的に指定します。
プリフライトリクエストの理解: 特定の条件下では、ブラウザがサーバーに対してプリフライトリクエストを送信し、実際のリクエストが許可されているかを確認します。このプロセスを理解し、適切に設定することが重要です。
CORSは、現代のウェブ開発において不可欠な要素であり、適切に実装することで、セキュリティを維持しつつ、リソースの柔軟な利用を可能にします。
CORSの設定
app.enableCors({
origin: ['http://localhost:5173', 'http://localhost:3000'],
allowedHeaders: 'Origin, X-Requested-With, Content-Type, Accept',
});
URLの末尾にスラッシュがあるかどうか('http://localhost:3000')が影響する場合があるため気を付ける
CORS設定では、特定のHTTPメソッド(GET, POST, PUT, DELETEなど)を許可する必要があります。デフォルトでは、GETとPOSTは許可されていますが、他のメソッドを使用する場合は、methodsオプションを追加する必要があります。
app.enableCors({
origin: ['http://localhost:5173', 'http://localhost:3000'],
allowedHeaders: 'Origin, X-Requested-With, Content-Type, Accept',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
});
フロントエンド側では、mode:"cors"をつける必要がある。
await fetch(`http://localhost:3000//${id}`, {
mode: "cors",