Access-Control-Allow-Credentials
使い方
クロスオリジンのリクエストは既定で、cookie、Authorization ヘッダー、TLS クライアント証明書といった認証情報を除外します。クライアントが認証情報モードを include に設定した場合、ブラウザが呼び出し元のスクリプトにレスポンスのボディとヘッダーを公開するには、サーバーが Access-Control-Allow-Credentials を値 true で返さなければなりません。
プリフライトのやり取りにおいて、このヘッダーは実際のリクエストが認証情報を運ぶことを許可されるかどうかを示します。プリフライトのレスポンスがこのヘッダーを省略するか true 以外の値を設定した場合、ブラウザは認証情報を伴うリクエストを完全にブロックします。
単純な CORS リクエスト(基本的な GET のようにプリフライトのステップがないもの)でも、ブラウザはレスポンスを受け取った後にこのヘッダーを確認します。ヘッダーがない場合、レスポンスは黙って破棄され、呼び出し元のコードには決して届きません。
注意
認証情報を含める場合、Access-Control-Allow-Origin ヘッダーは明示的なオリジンを指定しなければなりません。認証情報を伴うリクエストでワイルドカード * は許可されません。
true
唯一の有効な値です。このヘッダーを true として含めると、認証情報が存在する場合にレスポンスを公開するようブラウザに伝えられます。
Access-Control-Allow-Credentials: true
ヘッダーを省略した場合も、他の値を送った場合も効果は同じです。ブラウザはそのレスポンスを認証情報を伴わないものとして扱い、ボディを JavaScript に渡しません。
例
フロントエンドのアプリケーションが、認証情報を含めたクロスオリジンの fetch を送ります。サーバーは認証情報のヘッダー、明示的なオリジン、そしてキャッシュがオリジンごとに区別できるよう Vary ディレクティブを返します。
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Vary: Origin
認証情報を伴う POST リクエストのプリフライトにおいて、サーバーは許可するメソッドと認証情報のサポートの両方を伝えます。
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600
Vary: Origin
トラブルシューティング
認証情報を伴うクロスオリジンのリクエストは、CORS の連鎖のどこか 1 か所でも設定を誤ると、何のエラーもなく失敗します。
サーバーが Access-Control-Allow-Credentials: true を返しているのに cookie がクロスオリジンで送られない。クライアント側のコードが認証情報の送信を明示的に選択する必要があります。Fetch API ではリクエストのオプションに credentials: ‘include’ を渡します。XMLHttpRequest では send() を呼ぶ前に withCredentials = true を設定します。このフラグがなければ、サーバーのレスポンスに関わらずブラウザはクロスオリジンのリクエストから cookie と Authorization ヘッダーを取り除きます。
コンソールに「Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.」と表示される。Access-Control-Allow-Credentials が true の場合、Access-Control-Allow-Origin ヘッダーには明示的なオリジンを含めなければなりません。受信した Origin ヘッダーを読み取り、許可リストと照合して検証し、一致したオリジンをそのまま返し、レスポンスに Vary: Origin を加えてください。同じ規則は Access-Control-Allow-Headers と Access-Control-Allow-Methods にも当てはまります。認証情報を伴うリクエストでは、これらのヘッダーのワイルドカードはリテラル文字列として扱われます。
fetch() の呼び出しに credentials: ‘include’ がない。Fetch API の既定は credentials: ‘same-origin’ であり、クロスオリジンのリクエストでは認証情報が除外されます。{ credentials: ‘include’ } を明示的に渡してください。DevTools の Network タブでリクエストヘッダーを確認します。送信されるリクエストに Cookie ヘッダーがなければ、クライアントが明示的に選択していないということです。
XMLHttpRequest に withCredentials = true がない。Fetch API と同様に、XMLHttpRequest は withCredentials が true に設定されていない限りクロスオリジンで cookie を送りません。このプロパティは xhr.open() や xhr.send() を呼ぶ前に設定する必要があります。Axios のようなライブラリは、リクエスト設定で { withCredentials: true } として公開しています。
SameSite の cookie 属性がクロスオリジンの送信をブロックしている。現代のブラウザは、SameSite 属性が設定されていない場合に既定で SameSite=Lax を採用します。Lax の cookie は、クロスオリジンの POST やサブリソースのリクエストでは送られません。クロスオリジンで送る必要のある cookie には SameSite=None と Secure を設定してください。DevTools の Application 配下で属性を確認します。
Cookies。Secure がなければ、ブラウザは SameSite=None の cookie を完全に拒否します。
サードパーティ cookie の廃止が認証情報をブロックしている。Chrome をはじめとするブラウザはサードパーティ cookie を制限しつつあります。別のドメインが設定した cookie に依存するクロスオリジンのリクエストは、ますます機能しなくなっていきます。可能であれば Authorization ヘッダーを用いたトークンベースの認証へ移行するか、cookie へのアクセスを明示的に要求する Storage Access API を採用してください。展開前に問題を洗い出すため、Chrome の「Third-party cookie phaseout」フラグを有効にしてテストします。