vueでいつものようにaxios
を使ってサーバーと通信していました。
が、Twitterと連携させるときに以下のようなエラーが発生。
Cross-Origin Read Blocking (CORB) blocked cross-origin response https://api.twitter.com/oauth/authenticate?oauth_token=xxxxxxxxxxxxxx with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.
どうやらCORB(Cross Origin Request Blocking)
によってブロックされてしまったらしい。
正直意味がわからなかったので色々調べてみたらSame-Origin-Policy
が関わっていることが分かりました。
そもそもSame-Origin-Policyとは何なのか
**Same-Origin-Policy(同一オリジンポリシー)**とは、同じドメイン同士でしかやり取りできませんよ!というウェブセキュリティにおけるルールのことです。
あるオリジン(スキーム + ホスト + ポート)にアクセスして、そのリソースから異なるオリジンにAjax通信できないよう制限する仕組みで、スキーム、ホスト、ポート等が一つでも違えばアクセスできません。
サーバーが二つあるとしたらこんな感じです。
- クライアントがAサーバーにアクセス
- Aサーバーはクライアントにレスポンスを返す
- クライアントがBサーバーにAjax通信を送る
- Bサーバーから違うオリジンからアクセスするな!と怒られる。
https:://example.comからhttps::/test.com にAjax通信はできません。
なぜならホスト名が違うから。(ポートやスキームが違ってもだめ)
では今回のTwitter認証のエラーに当てはめてみましょう。
-
localhost
にアクセス -
localhost
はレスポンスを返す -
localhost
からTwitterAPI
にAjax通信を送る - 違うオリジン(URL)からアクセスするな!と怒られる。
Twitter側のAPIサーバーで、私はこのURLからのアクセスは許可しないよ!と拒否されてたということですね。
そこで、今回のようにsome-origin-policy
に弾かれずに異なるドメイン同士で安全にリソースを共有するための仕組みが**CORS(Cross Origin Resource Sharing)
**というもの。
アクセスするには、通信される側のサーバーで特定のドメインからのアクセスを許可してあげる必要があります。
詳しくは調べていただければと思うのですが、
例えばサーバー側で、以下のようにヘッダーで許可するドメインを設定しなければなりません。
Access-Control-Allow-Origin: 'https://example.com'
もちろん僕たちがTwitterのAPIサーバーをいじることはできないので、諦めることに。
解決法 Ajax通信をやめる
長々と調べごとをしてましたが、そもそもAjax通信する必要性がないことに気づいたので、XMLHttpRequestではなく、単純にHTTPRequestを送るように変更することで解決。
axios.get("users/auth/twitter")
↓
document.location.pathname = "users/auth/twitter"
フロントとバックエンドを分けると認証周りでつまづくことも多いですが、何かセキュリティ的に問題等ありましたらコメントいただけると幸いです。