サードパーティのストレージ アクセスをブロックするブラウザで signInWithRedirect を使用する場合のベスト プラクティス
本ドキュメントでは、サードパーティ Cookie をブロックするブラウザでリダイレクト ログインを使用する場合のベスト プラクティスについて説明します。 本番環境のすべてのブラウザで signInWithRedirect()
を意図したとおりに機能させるには、ここに記載されているオプションのいずれかに従う必要があります。
概要
お客様とお客様のユーザーに対してシームレスな signInWithRedirect()
フローを提供するために、Firebase Authentication JavaScript SDK では、アプリの Firebase Hosting ドメインに接続するクロスオリジンの iframe を使用しています。ただし、このメカニズムは、サードパーティのストレージ アクセスをブロックするブラウザでは機能しません。
ブラウザのストレージ パーティショニング機能を無効にするようユーザーに求めることは現実的ではないため、ユースケースの具体的な仕様に応じて、代わりに以下のいずれかの設定オプションをアプリに適用する必要があります。
- Firebase Hosting を使用して
firebaseapp.com
のサブドメインでアプリをホストする場合、この問題による影響はなく、特別な対応は必要ありません。 - Firebase Hosting を使用してカスタム ドメインまたは
web.app
のサブドメインでアプリをホストする場合は、オプション 1 を使用します。 - Firebase 以外のサービスでアプリをホストしている場合は、オプション 2、オプション 3、オプション 4、またはオプション 5 を使用します。
オプション 1: カスタム ドメインを authDomain
として使用するように Firebase 構成を更新する
カスタム ドメインを使用して Firebase Hosting でアプリをホストしている場合は、カスタム ドメインを authDomain
として使用するように Firebase SDK を構成できます。これにより、アプリと認証 iframe が同じドメインを使用するようになり、ログインの問題を回避できます(Firebase Hosting を使用しない場合は、別のオプションを使用する必要があります)。認証に使用しているものと同じプロジェクトにカスタム ドメインを設定してあることを確認します。
カスタム ドメインを認証ドメインとして使用するように Firebase 構成を更新する手順は次のとおりです。
カスタム ドメインを
authDomain
として使用するように Firebase JS SDK を構成します。const firebaseConfig = { apiKey: "<api-key>", authDomain: "<the-domain-that-serves-your-app>", databaseURL: "<database-url>", projectId: "<project-id>", appId: "<app-id>" };
OAuth プロバイダの承認済みリダイレクト URI のリストに新しい
authDomain
を追加します。この方法はプロバイダによって異なりますが、一般的な手順は、お使いのプロバイダの「始める前に」セクション(例: Facebook プロバイダ)で確認できます。承認のために更新された URI はhttps://<the-domain-that-serves-your-app>/__/auth/handler
のようになります。末尾の/__/auth/handler
が重要です。同様に、SAML プロバイダを使用している場合は、新しい
authDomain
を SAML Assertion Consumer Service(ACS)の URL に追加します。continue_uri
が承認済みドメインのリストに含まれていることを確認します。必要に応じて Firebase Hosting で再デプロイし、
/__/firebase/init.json
でホストされている最新の Firebase 構成ファイルを取得します。
オプション 2: signInWithPopup() に切り替える
signInWithRedirect()
ではなく signInWithPopup()
を使用します。アプリのコードの残りの部分は同じままですが、UserCredential オブジェクトの取得方法が異なります。
Web version 9
// Before
// ==============
signInWithRedirect(auth, new GoogleAuthProvider());
// After the page redirects back
const userCred = await getRedirectResult(auth);
// After
// ==============
const userCred = await signInWithPopup(auth, new GoogleAuthProvider());
Web version 8
// Before
// ==============
firebase.auth().signInWithRedirect(new firebase.auth.GoogleAuthProvider());
// After the page redirects back
var userCred = await firebase.auth().getRedirectResult();
// After
// ==============
var userCred = await firebase.auth().signInWithPopup(
new firebase.auth.GoogleAuthProvider());
```
ポップアップ ログインはユーザーにとって必ずしも理想的なものではありません。ポップアップはデバイスやプラットフォームによってブロックされることがあり、モバイル ユーザーにとってはフローがスムーズではありません。ポップアップの使用がアプリにとって問題となる場合は、他のいずれかのオプションを採用する必要があります。
オプション 3: firebaseapp.com へのプロキシ認証リクエスト
signInWithRedirect
フローでは、最初にアプリのドメインから Firebase 構成の authDomain
パラメータで指定されたドメイン(デフォルトでは authDomain
は、ID プロバイダにリダイレクトするログイン ヘルパーコードをホストします。これが成功すると、再びリダイレクトしてアプリのドメインに戻ります。
認証フローがアプリのドメインに戻ると、ログイン ヘルパー ドメインのブラウザ ストレージへのアクセスが行われます。(コードを自己ホストするための)このオプションと次のオプションにより、ブラウザによってブロックされるクロスオリジンのストレージ アクセスをなくすことができます。
アプリサーバーにリバース プロキシを設定して、
https://<app domain>/__/auth/
への GET/POST リクエストがhttps://<project>.firebaseapp.com/__/auth/
に転送されるようにします。この転送がブラウザに対して透過的であるようにします。302 リダイレクトを使用してこれを行うことはできません。nginx を使用してカスタム ドメインを提供する場合、リバース プロキシ構成は次のようになります。
# reverse proxy for signin-helpers for popup/redirect sign in. location /__/auth { proxy_pass https://<project>.firebaseapp.com; }
オプション 1 の手順に沿って、承認済みの
redirect_uri
、ACS の URL、authDomain
を更新します。アプリを再デプロイすると、クロスオリジンのストレージ アクセスは行われなくなります。
オプション 4: ログイン ヘルパー コードを自社ドメイン内でホストする
クロスオリジンのストレージ アクセスをなくす別の方法として、Firebase ログイン ヘルパーコードを自社でホストするという方法があります。ただし、この方法は Apple ログインと SAML では機能しません。このオプションは、オプション 3 のリバースプロキシ設定を実行できない場合にのみ使用してください。
ヘルパーコードをホストする手順は次のとおりです。
次のコマンドを実行して、
<project>.firebaseapp.com
ロケーションからホストするファイルをダウンロードします。mkdir signin_helpers/ && cd signin_helpers wget https://<project>.firebaseapp.com/__/auth/handler wget https://<project>.firebaseapp.com/__/auth/handler.js wget https://<project>.firebaseapp.com/__/auth/experiments.js wget https://<project>.firebaseapp.com/__/auth/iframe wget https://<project>.firebaseapp.com/__/auth/iframe.js wget https://<project>.firebaseapp.com/__/firebase/init.json
自社のアプリドメインで上記のファイルをホストします。ウェブサーバーが
https://<app domain>/__/auth/<filename>
とhttps://<app domain>/__/firebase/init.json
に応答できるようにします。ファイルをダウンロードしてホストするサーバー実装のサンプルをご確認ください。 ファイルを定期的にダウンロードして同期し、最新のバグの修正や機能が確実に反映されるようにすることをおすすめします。
オプション 1 の手順に沿って、承認済みの
redirect_uri
とauthDomain
を更新します。アプリを再デプロイすると、クロスオリジンのストレージ アクセスは行われなくなります。
オプション 5: プロバイダのログインを独自に処理する
Firebase Authentication SDK には、複雑なロジックをラップし、別の SDK を組み込まなくても済むようにするための便利なメソッドとして、signInWithPopup()
と signInWithRedirect()
が用意されています。これらのメソッドをまったく使用しないという選択肢もあります。その場合は、プロバイダに個別にログインし、signInWithCredential()
を使用してプロバイダの認証情報を Firebase Authentication の認証情報と交換します。たとえば、Google ログイン SDK(サンプルコード)を使用して Google アカウントの認証情報を取得してから、次のコードを実行して、新しい Google 認証情報をインスタンス化できます。
Web version 9
// `googleUser` from the onsuccess Google Sign In callback.
// googUser = gapi.auth2.getAuthInstance().currentUser.get();
const credential = GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token);
const result = await signInWithCredential(auth, credential);
Web version 8
// `googleUser` from the onsuccess Google Sign In callback.
const credential = firebase.auth.GoogleAuthProvider.credential(
googleUser.getAuthResponse().id_token);
const result = await firebase.auth().signInWithCredential(credential);
signInWithCredential()
を呼び出した後のアプリの他の部分は、それまでと同じように機能します。
Apple の認証情報を取得する手順については、こちらをご覧ください。