LoginSignup
6
7

More than 5 years have passed since last update.

XHR中にクロスドメインのリダイレクトが発生した時に、リダイレクト先のページに遷移できない

Last updated at Posted at 2017-05-03

XHR中にクロスドメインのリダイレクトが発生した時に、リダイレクト先のページに遷移できない

上記についてハマった時のメモを残す。

状況

認証サーバ(OpenID Connect 準拠)を作っている。この時、以下のユースケースで認証が成立する。

  1. アプリケーションから認証サーバにログイン処理が委譲される
  2. 認証サーバで認証がすみ、ユーザにアプリケーションに対する同意を求める
  3. 認証サーバはユーザ(UA)をアプリケーションのURIにリダイレクトさせる
  4. アプリケーションは認証サーバから取得した情報を元に、ユーザを認証済みまたは拒否する

上記の3のプロセスで、リダイレクト先のページに遷移できなかった。

エラーメッセージ
XMLHttpRequest cannot load <DESTINATION_HOSTNAME>. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin <SENDER_HOSTNAME> is therefore not allowed access.

以下、問題の焦点を分割し、それぞれについての対策を記述している。

XHRでGETできない

プリフライトリクエストを受信できるようにサーバを設定

サンプルとなるアプリケーションのサーバサイドは、S3のWebホスティングを使っている。
ここでは当該バケットの、CORS設定を下記のように変更した(See here)。

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

プリフライトリクエストを送信できるようにリクエストヘッダを追加

リクエストヘッダに以下を追記(See here)した。
これにより、ブラウザからプリフライトリクエストが飛ぶことになる。

Requets
    .post('http://localhost:4000/authorization')
    .withCredentials()
    .set('Content-type', 'application/x-www-form-urlencoded')
    .set('Access-Control-Allow-Origin', '*')
    .set('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS')
  .  set('Access-Control-Allow-Headers', 'Content-Type, Content-Range, Content-Disposition, Content-Description')

XHRでリダイレクトできない

withCredentialsへの対応

リダイレクト先へのXHRではCookieを送信する必要はないのだが、大元のエンドポイントに対するリクエストには送信する必要があった。
このため、最終的なリダイレクト先に対してもwithCredentials = trueの状態でGETを行なっているようだ。
ゆえに、サーバのレスポンスヘッダAccess-Control-Allow-Origin*だとNGになる(See here)。この場合はサーバ設定にて送信元ホストを直接指定することで回避した。

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>http://localhost:4000</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

終わりに

やったこと 必要性
アプリケーション側のCORS対応 やるべき
認証サーバ側のプリフライトリクエスト対応 やるべき
アプリケーション側のwithCredentials対応 やりたくはなかったが、仕方なく

3つめについて、リダイレクト先(アプリケーション)には単純にGETリクエスト送信したかっただけだが、withCredentials対応をする必要があった。このためアプリケーションのサーバ設定で、Access-Control-Allow-Originに送信元ホストを個別に指定することになってしまった。

なお、CORS関連の予備知識としてまとめた投稿はこちらにある。

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7