Webアプリケーション開発において、クロスオリジンリクエストは一般的な課題です。特にCookieを扱う場合、ブラウザとサーバーの連携が重要になります。本稿では、クロスオリジン通信におけるCookieの取り扱いと関連する設定について解説します。
基本的なクロスオリジンリクエスト
開発者Aがフロントエンドから異なるオリジンのAPI(例: /login)にPOSTリクエストを送信したところ、ブラウザによってレスポンスがブロックされました。コンソールにはCORSポリシー違反のエラーが表示されます。
この問題は、サーバー側で適切なAccess-Control-Allow-Originヘッダーを設定することで解決できます。例えば:
Access-Control-Allow-Origin: *
この設定により、すべてのオリジンからのリクエストが許可されます。ブラウザはレスポンスを受け取った後、このヘッダーの存在を確認してJavaScriptへのデータ転送を許可します。
非シンプルリクエストの対応
リクエストボディをJSON形式に変更すると、再びCORSエラーが発生します。これはContent-Typeがapplication/jsonとなるため、リクエストが「非シンプルリクエスト」に分類されるためです。
シンプルリクエストの条件:
- HTTPメソッドがGET、HEAD、POSTのいずれか
- CORSセーフリストに含まれるヘッダーのみ使用
- Content-Typeがtext/plain、multipart/form-data、application/x-www-form-urlencodedのいずれか
非シンプルリクエストでは、プリフライトリクエスト(OPTIONSメソッド)が自動的に送信されます。サーバーはこのリクエストにも適切なCORSヘッダーで応答する必要があります。
Cookieを伴うクロスオリジンリクエスト
セッションベースの認証では、ログイン成功後にサーバーからSet-Cookieヘッダーが送信されます。しかし、クロスオリジンリクエストでは、デフォルトでCookieが送信されません。
Fetch APIを使用する場合:
fetch('https://api.example.com/data', {
method: 'GET',
credentials: 'include'
})
XMLHttpRequestを使用する場合:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.withCredentials = true;
xhr.send();
SameSite属性とSecureフラグ
クロスオリジンでCookieを送信するには、サーバー側でCookieのSameSite属性をNoneに設定し、同時にSecureフラグを有効にする必要があります。これによりHTTPS接続が必須となります。
Set-Cookie: sessionId=abc123; SameSite=None; Secure
これらの設定はCSRF攻撃からの保護とセキュリティのバランスを考慮したものです。
重要なCORS関連ヘッダー
- Access-Control-Allow-Origin: 許可するオリジンを指定
- Access-Control-Allow-Credentials: 資格情報の送信を許可
- Access-Control-Allow-Headers: 許可するリクエストヘッダー
- Access-Control-Allow-Methods: 許可するHTTPメソッド
クロスオリジン通信を正しく設定するには、リクエストとレスポンスの両方のヘッダーを理解することが不可欠です。