LoginSignup
2
7

More than 3 years have passed since last update.

OAuth認証アプリのCloudFront設定でハマった話

Last updated at Posted at 2020-08-01

はじめに

独自ドメインの小さなWebアプリを、AWSで以下のお安い構成でセットアップしてみました。

  • Route53 (独自ドメインを管理)
  • AWS Certificate Manager (ACM。SSL証明書を管理)
  • CloudFront
  • EC2

CloudFrontはキャッシュ用のエッジサーバとしてではなく、ACMと紐付けてSSLを利用したいため配置しています。
しかし、この構成にしたところアプリに実装していたOAuth認証が急に動かなくなりました。。。

最終的にCloudFrontの設定を見直して解決できたので、忘れないようにメモとして残しておきます。
同じように悩んだ人の参考になれば幸いです。

最終的な設定だけ見たい方は、まとめをどうぞ

GoogleのOAuth認証が通らなくなった

もともと、静的なWebコンテンツを CloudFront+S3 の構成でSSLでホストしていたため、それに倣ってCloudFront+EC2 もセットアップしてみました。
CloudFrontのキャッシュ設定はほぼデフォルトのままです。

いざアプリケーションでGoogleのOAuth認証してみると・・・
スクリーンショット 2020-08-01 18.08.34.png

エラー 400: redirect_uri_mismatch
The redirect URI in the request, http://***.ap-northeast-1.compute.amazonaws.com/login/oauth2/code/google, does not match the ones authorized for the OAuth client.

GoogleのOAuthで設定したリダイレクトURIにマッチしないエラーとなりましたorz

上記のエラーメッセージを見ると、認証後のリダイレクト先がEC2のパブリックDNS

http://*****.ap-northeast-1.compute.amazonaws.com/...

になってしまっているようです。

確かにGoogleのOAuth設定で、リダイレクト先に独自ドメインのみを許可しているので、 それ以外のURIにリダイレクトできないのは正しい制御ではあるのですが・・・

なぜリダイレクト先がEC2のパブリックDNSになってしまう?

リダイレクト用のURIはアプリ側でホスト名を設定して生成しています。
つまり、 EC2に独自ドメインのホスト名が渡ってきていないことが問題のようです。

ホスト名はリクエストヘッダで指定するので、改めてCloudFrontの設定をみてみると・・・

スクリーンショット 2020-08-01 22.04.01.png

怪しい設定がありました。

Cache Based on Selected Request Headers とは

この項目を調べるにあたり、以下の記事がとても参考になりました。
https://michimani.net/post/aws-about-cache-spec-of-cloudfront/#cache-based-on-selected-request-headers-1

どうやらCloudFrontはエッジサーバとしてコンテンツをキャッシュするために、デフォルトではリクエストヘッダの値を考慮しないだけでなく、 オリジンにリクエストヘッダを転送しないようです。

公式の説明文 を読むと、[None(Improves Caching)] の説明には特に記載がないですが、 [All(すべて)] には

代わりに、CloudFront はすべてのリクエストをオリジンに送信します。

とありました。

なるほど、こいつが元凶 この設定を見直す必要があったようです。

オリジンにリクエストヘッダを転送する設定

今回、オリジンはEC2のためキャッシュは不要、かつリクエストヘッダも転送して欲しいため [All] に変更しました。
スクリーンショット 2020-08-01 22.34.30.png
これで無事にEC2にホスト名を含むリクエストヘッダが転送されるはずです。

設定変更後にアプリのログインボタンを押下すると・・・
スクリーンショット 2020-08-01 22.59.16.png

無事にアカウント選択画面まで進みました!

アカウントを選択してみると、、、

まさかのエラーorz
スクリーンショット 2020-08-01 18.40.07.png

これはアプリ側で用意しているエラーレスポンスですが、つまり

Status Code: 401 Unauthorized

のようです。
GoogleのOAuthからアプリへのリダイレクトは成功していますが、アプリ側の処理で問題があるようです。

Forward Cookies と Query String Forwarding and Caching

意気消沈しながらも、改めてCloudFrontの設定をみてみると・・・
スクリーンショット 2020-08-01 23.36.21.png

CookieやURIのクエリパラメータに関する設定がありました。
この項目も以下の記事に詳しく説明されていました。

これらの設定も、デフォルトではコンテンツをキャッシュするために値の考慮をしないだけでなく、
Cookieやクエリパラメータがオリジンに転送されないようです。

つまりこの設定もNone (Improves Caching)だとオリジンに転送しないんですね。

オリジンにCookieとクエリパラメータを転送する設定

すべてのCookie、クエリパラメータをオリジンに転送して欲しいため[All]に変更しました。
スクリーンショット 2020-08-02 0.11.54.png

以上の設定で、無事にCookieおよびURIのクエリパラメータがオリジンに転送されるようになりました。

画面ショットは省きますが、これでCloudFront+EC2の構成で無事にOAuth認証でログインが行えるようになりました:clap_tone1:

まとめ

CloudFrontをEC2などAppサーバの手前に配置する場合、以下の項目でオリジンへの転送の設定を行う必要があります。

  • Cache Based on Selected Request Headers
    リクエストヘッダをオリジンに転送するため[All]を指定

  • Forward Cookies
    Cookieをオリジンに転送するため[All]を指定

  • Query String Forwarding and Caching
    クエリパラメータをオリジンに転送するため[Forward all, cache based on all]を指定

参考

2
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
2
7