KDOC 93: Access-Control-Allow-Headersを調べた

この文書のステータス

  • 作成
    • 2024-02-15 貴島
  • レビュー
    • 2024-02-18 貴島

概要

POSTリクエストは成功するのに、GETリクエストがCORSエラーな状態になった。デベロッパーツールを見るとCORSエラーが出ていた。真の違いの理由は、トークンでAuthorizationヘッダーを使っていたことだった。調べて Access-Control-Allow-Headers を返すようにしたら解決したが、知らなかったので調べる。

何か

Access-Control-Allow-Headersは、同一オリジンでないときに、実際のリクエスト(プリフライトリクエストと対置して)で使用できるヘッダーの種類を示すものだ。デフォルトではAccept, Accept-Language, Content-Language, Content-Typeだけが許可されていて、Authorizationヘッダーは含まれていない。

Google Chromeの挙動を見る限り、同一オリジンでないときに許可してないヘッダーが含まれていた場合は、問答無用でCORSエラーになる。

流れ

プリフライトリクエストから一連の流れを見る。まず、ブラウザは実際のリクエスト前にOriginヘッダーが同一でないのを見て、CORSによってリソースにJavaScriptコードがアクセスできるか判断しようとする。検証するため、ブラウザは実際に行いたいリクエストを元にプリフライトリクエストを作成する。

curl -v \
     -H "Origin: nandemoii.com" \
     -H "Access-Control-Request-Method: GET" \ 👈
     -H "Access-Control-Request-Headers: Authorization" \ 👈
     -H "Content-Type: application/json" \
     -X OPTIONS \
     'http://localhost/manage/manage/projects'
  • 実際に行いたいリクエストのメソッドは Access-Control-Request-Method で表現する
  • 実際に行いたいリクエストのヘッダーは Access-Control-Allow-Headers で表現する
  • プリフライトリクエスト自体はOPTIONSメソッド
< HTTP/1.1 200 OK
< Date: Thu, 15 Feb 2024 13:19:49 GMT
< Server: Apache
< access-control-allow-origin: *
< Content-Length: 0
< Content-Type: text/html; charset=UTF-8
< Cache-Control: max-age=1
< Expires: Thu, 15 Feb 2024 13:19:50 GMT
< Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE 👈
< Access-Control-Allow-Headers: Authorization 👈
<

↑ここで、Webサーバはリソースの共有方針をブラウザに教える。Webサーバは、5つのリクエストメソッドを許可し、リクエストヘッダーはAuthorizationを許可している。ここで、プリフライトリクエストに含まれていた使用予定のメソッド、ヘッダーがすべて含まれていることがわかる。これによって、Javascriptがリソースにアクセスできる権限が確認できたことになる。

確認ののち、本番のリクエストを行う。

curl -v \
     -H "Origin: nandemoii.com" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer xxxx" \
     'http://localhost/manage/manage/projects'
< HTTP/1.1 200 OK
< Date: Thu, 15 Feb 2024 13:23:15 GMT
< Server: Apache
< Content-Length: 460
< Content-Type: application/json; charset=UTF-8
< Vary: Accept-Encoding
< Cache-Control: max-age=1
< Expires: Thu, 15 Feb 2024 13:23:16 GMT
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
< Access-Control-Allow-Headers: Authorization

参考

関連