【翻訳記事】CORSを理解する

レバテックキャリアは
ITエンジニア・Webクリエイター専門の転職エージェントです

Bartosz Szczeciński氏がブログで投稿した記事「Understanding CORS (Posted Jan 28, 2018)」を翻訳してご紹介しています。
なお、この記事は原著者の許諾を得て翻訳・掲載しています。


「OK, but no(OKですが、○○がありません)」

AJAX呼び出しを使って作業したことがある方ならば、おそらくブラウザコンソールに表示される以下のようなエラーをご存知でしょう。

ブラウザコンソールに表示されるエラーメッセージの画像

https://example.com/を読み込めませんでした。要求されたリソースに「Access-Control-Allow-Origin」ヘッダーが存在しません。そのため、Origin「https://anfo.pl」のアクセスが許可されていません。不透明な応答が必要な場合は、リクエストのモードを「no-cors」に設定して、CORSを無効にしてリソースを取り出してください。

このメッセージが表示された場合、応答は失敗したものの、[ネットワーク]タブに移動すると返されたデータが表示されることを意味します。

クロスオリジンリソースシェアリング(CORS)

この振る舞いは、ブラウザCORSの実装の影響です。

CORSが標準化される前に、セキュリティ上の理由から、異なるドメインのAPIエンドポイントを呼び出す方法はありませんでした。これは、Same-Origin Policy(同一オリジンポリシー)によってブロックされていました(現在もある程度ブロックされています)。

CORSは、あなたが行ったリクエストを許可すると同時に、不正なJSによって行われたリクエストをブロックするためのメカニズムです。以下へのHTTPリクエストを行うたびにトリガーされます。

・別のドメイン(例:example.comのサイトがapi.comを呼び出すこと)

・別のサブドメイン(例:example.comのサイトがapi.example.comを呼び出すこと)

・別のポート(例:example.comのサイトがexample.com:3001を呼び出すこと)

・別のプロトコル(例:https://example.comのサイトがhttp://example.comを呼び出すこと)

このメカニズムは、様々なウェブサイト(例:Google Ads経由で表示される広告)にスクリプトを埋め込む攻撃者が、*あなたの*の資格情報を使ってトランザクションを作成してログインした場合に、www.yourbank.comへのAJAX呼び出しを行うのを防ぐことができます。

サーバーが「単純な」GETまたはPOSTリクエストに対して特定のヘッダーで応答しない場合、リクエストは送信され、データも受信されますが、ブラウザがJavaScriptの応答へのアクセスを許可しません。

あなたのブラウザが「単純ではない」リクエスト(例:クッキーを含むリクエスト、またはContent-typeapplication/x-ww-form-urlencodedmultipart/form-dataまたはtext-plain以外のリクエスト)を出そうとしている場合、preflightと呼ばれるメカニズムが使用され、OPTIONSリクエストがサーバーに送信されます。

「単純ではない」リクエストの一般的な例は、クッキーまたはカスタムヘッダーを追加したものです。あなたのブラウザがそのようなリクエストを送信し、サーバーが正しく応答しない場合、preflight呼び出しのみが行われます(余分なヘッダーなし)が、ブラウザが意図した実際のHTTPリクエストは送信されません。

Access-Control-Allow-○○?

CORSはリクエストと応答の両方でいくつかのHTTPヘッダーを使用します。しかし、作業を続けるために理解しなければならないものは以下のとおりです。

Access-Control-Allow-Origin

このヘッダーはサーバーによって返されることを意図しており、リソースにアクセスできるクライアントドメインを示します。値は以下のいずれかです。

* - 任意のドメインをすべて許可する

・完全修飾ドメイン名(例:https://example.com)

クライアントが認証ヘッダー(例:クッキー)を渡す必要がある場合、値を*にすることはできません。完全修飾ドメインにしなければなりません。

Access-Control-Allow-Credentials

このヘッダーは、サーバーがクッキーによる認証をサポートしている場合、応答にのみ存在する必要があります。この場合の唯一の有効な値はtrueです。

Access-Control-Allow-Headers

サーバーがサポートしようとしているリクエストヘッダー値のコンマ区切りのリストを提供します。カスタムヘッダーを使用する場合(例:x-authentication-token)、OPTIONS呼び出しに対するこのACAヘッダー応答でそれを返す必要があります。さもないと、リクエストはブロックされます。

Access-Control-Expose-Headers

同様に、この応答には、呼び出しに対する実際の応答に存在するヘッダーのリストが含まれている必要があり、クライアントが使用できるようにする必要があります。その他のヘッダーはすべて制限されます。

Access-Control-Allow-Methods

サーバーがサポートしようとしているHTTPリクエストタイプの動詞(例:GETPOST)のコンマ区切りのリストです。

オリジン

このヘッダーは、クライアントが出しているリクエストの一部であり、アプリケーションが開始されたドメインが含まれます。セキュリティ上の理由から、ブラウザはこの値を上書きすることはできません。

CORS「エラー」の修正方法

CORSの振る舞いはエラーではないことを理解しておく必要があります。これは、あなたのユーザー、あなた自身、またはあなたが呼び出しているサイトを保護するために、期待どおりに機能するメカニズムです。

適切なヘッダーが欠如しているのは、間違ったクライアント側の実装(例:APIキーなどの認証データの欠落)のせいである場合があります。

あなたが直面しているシナリオに応じて、「エラーを修正する」方法がいくつかあります。

A - フロントエンドを開発しており、バックエンドを開発している人が部下または知り合いの場合

これが最良のシナリオです。あなたが呼び出しているサーバーで適切なCORSの応答を実装できるはずです。 APIがNode向けのexpressを使用している場合は、単純なcorsパッケージを使用できます。サイトを適切に保護したい場合は、Access-Control-Allow-Originヘッダーにホワイトリストを使用することを検討してください。

B - フロントエンドを開発しているが、現在バックエンドを制御する権限を持っておらず、一時的な解決策が必要な場合

これは2番目に良いシナリオです。なぜなら、ほとんどAパターンと同じで、少しの時間的な制約があるだけだからです。この問題を一時的に解決するには、ブラウザにCORSのメカニズムを無視させることができます。例えば、ACAO Chrome拡張機能を使用するか、Chromeを以下のフラグで実行してCORSのメカニズムを完全に無効にすることができます。

chrome --disable-web-security --user-data-dir

重要:これにより、ブラウザセッション全体の間、すべてのウェブサイトのメカニズムが無効になることを忘れないでください。慎重に使用してください。

もう1つの選択肢は、devServer.proxyを使用するか(webpackを使用してアプリケーションを提供していることを前提としています)、https://cors-anywhere.herokuapp.com/のようなCORS-as-a-service(CORSに基づいたサービス)ソリューションを使用することです。

C - フロントエンドを開発しており、バックエンドを制御する権限を持っておらず、これからも制御することはない場合

さて、問題が複雑になってきました。まず、サーバーが適切なヘッダーを送信していない理由を確認する必要があります。

もしかすると、サードパーティのアプリがそのAPIにアクセスすることを許可していないのかもしれません。もしかすると、そのAPIはブラウザ側ではなく、サーバー側のアプリケーションでのみ使用できるように意図されているのかもしれません。もしかすると、URLにソートの許可トークンを送信する必要があるのかもしれません。

あなたがまだブラウザ経由でデータにアクセスできるはずだと思う場合は、解決策Bパターンで行ったのと同様に、ブラウザアプリケーションとAPIの間にある独自のプロキシを作成する必要があります。

間にプロキシを追加する

プロキシは、プロキシ自体がクライアントとの通信時にCORSを適切にサポートしている限り、アプリケーションと同じドメインで実行する必要はありません。プロキシとAPIとの間の通信が、CORSをサポートしている必要性は全くありません。

独自のプラットフォームを作成してもいいですし、https://www.npmjs.com/package/cors-anywhereのような既成のソリューションを使用しても構いません。

このようなアプローチは、資格情報をサポートしたい場合に、セキュリティ上のリスクを引き起こす可能性があることに注意してください。

CORSのさらなる詳細

CORSについてさらに知りたい場合は、詳細なMDNの記事をご覧ください。



CREDIT:原著者の許諾のもと翻訳・掲載しています。

[原文]Understanding CORS (Posted Jan 28, 2018) by Bartosz Szczeciński
 


関連する記事

人気の記事

スキルアップ記事トップへ

無料サポート登録簡単30秒

【厚生労働省】職業紹介事業許可番号(13-ユ-308734)

  • STEP1
  • STEP2
  • STEP3
  • 次のstepで入力すると返事が来る!
  • プロフィール入力すると返事が来る!
  • ご希望の条件を選択してください

    ご希望の勤務形態

    必須

    ご希望の勤務地

    任意

  • プロフィールをご入力ください!必須入力項目はこのページで終わりです。

    氏名

    必須

    氏名かな

    必須

    生年月日

    必須

    電話番号

    必須

    メールアドレス

    必須

  • スキルシート・ポートフォリオをお持ちの方はアップロードしてください

    スキルシート

    任意

    提出しておくことで
    迅速なご紹介が可能に!

    職務経歴書

    ドラッグアンドドロップ or ファイルを選択 選択されていません

    履歴書

    ドラッグアンドドロップ or ファイルを選択 選択されていません

    スキルシートを確認しています...

    スキルシートを確認しています...

    ※ファイルは5MB以下で対応するファイル形式 ? でアップロードしてください
    Microsoft Office .xls .xlsx .doc .docx .ppt .pptx
    KINGSOFT Office .xls .xlsx .doc .docx .ppt
    iWork .numbers .pages .key
    LibreOffice .ods .odt .odp
    OpenOffice .ods .odt .odp
    その他 .pdf

    ポートフォリオURL

    任意

    ?

    ポートフォリオとは主にクリエイターの方が自己PRのために過去の作品や制作実績をまとめた作品集の事です。

    ポートフォリオをWeb上で公開されている方はそのURLを、データでお持ちの方は作品データをアップしたURLを入力してください。

    ※データをアップされる場合は、保存期間や容量制限の少ないGoogleドライブを推奨しています。

    その他ご要望

    任意

  • 下記の内容をご確認いただき問題ないようでしたら、送信してください

    プロフィール入力すると返事が来る!

    • ご希望の勤務形態 必須

    • ご希望の勤務地 任意

      第一希望:
      第二希望:

    • 氏名 必須

    • 氏名かな 必須

    • 生年月日 必須

    • 電話番号 必須

    • メールアドレス 必須

    • 職務経歴書 任意

    • 履歴書 任意

    • ポートフォリオURL 任意

    • その他ご要望 任意

    個人情報の取り扱い 」と「 利用規約 」に同意の上、 『同意して登録する』 ボタンをクリックして下さい。

プライバシーマーク

レバテック株式会社は「プライバシーマーク」使用許諾事業者として認定されています。
個人情報の秘密は厳守します。ご入力いただいた情報は許可を頂くまで求人企業に公開することはありませんので、ご安心ください。

申し込みに関するご注意
以下の方は弊社の事業基盤、求人動向から、ご提案のご連絡までお時間をいただく可能性があります。ご了承ください。
IT業界、または希望職種が未経験の方
レバテックキャリア対象エリア以外での勤務地、また在宅での作業を希望される方