Firefox や Safari で Firebase Authentication の signInWithRedirect を使用する(Firebase Hosting 未使用)

Firebase Hosting を使わず、サードパーティのストレージアクセスをブロックするブラウザで Firebase Authentication の signInWithRedirect を使用するための対応を行ったのでメモする。

環境

  • Next.js v13.2.1
  • Firebase v9.17.1
    • Firebase Authentication で Google 認証のみ使用
  • Vercel

概要

サードパーティのストレージ アクセスをブロックするブラウザで signInWithRedirect を使用する場合のベスト プラクティス に記載の通り、

お客様とお客様のユーザーに対してシームレスな signInWithRedirect() フローを提供するために、Firebase Authentication JavaScript SDK では、アプリの Firebase Hosting ドメインに接続するクロスオリジンの iframe を使用しています。ただし、このメカニズムは、サードパーティのストレージ アクセスをブロックするブラウザでは機能しません。

という問題がある。

Firebase Hosting を使用しない場合に取れる選択肢が幾つか上記ドキュメントに列挙されているが、signInWithPopup() に切り替えるのはポップアップがブロックされてしまう問題があるので論外。

すると次に推奨されるのがオプション 3: firebaseapp.com へのプロキシ認証リクエストである。

これを Next.js + Vercel でやっていく。

対応内容

まず最初に、この対応はローカル環境では確認できない(と思う)。
なぜなら Firebase JS SDK の構成で authDomain に localhost:3000 のようなポート番号付きのドメインを指定するとエラーになるからである。
Google 認証を行ったときのリダイレクト先はこの authDomain を見るため、localhost を指定しても動かない。
よってローカル環境ではこの対応を行わない。

ということで Vercel にデプロイする前提で対応内容を書いていく。

Google Cloud Console

Firebase Authentication で Google ログインの設定をしたとき、Google Cloud Console のほうに自動的にプロジェクトが作られている。
自動で作られたプロジェクトを選択し、「API とサービス>認証情報>OAuth 2.0 クライアント ID」に移動して下記を設定する。
(説明のため、本番環境フロントの URL は https://example.com とする)

  • 承認済みの JavaScript 生成元: https://example.com
  • 承認済みのリダイレクト URI: https://example.com/__auth/handler

Next.js の設定

Rewrites という機能を使い、https://example.com/__/auth/* への GET/POST リクエストが https://<project>.firebaseapp.com/__/auth/* に転送されるようにする。 next.config.js に下記の内容を記載する。

module.exports = {
  async rewrites() {
    return [
        {
          source: "/__/auth/:slug*",
          destination: "https://<project>.firebaseapp.com/__/auth/:slug*",
        },
    ];
  },
}

<project>.firebaseapp.com の部分は実際には環境変数を使っていると思うので自身の設定に合わせて書き換える。

次に、Content Security Policy の設定をしている場合は追加で設定が必要になる場合がある。
エラー内容を見ながら必要なものを指定してほしいが、私の場合は下記が必要だった。

  • script-src: ’nonce-firebase-auth-helper’ を追加
  • connect-src: https://www.googleapis.com/ を追加

最後に firebaseConfig を指定している箇所で、authDomain<project>.firebaseapp.com から example.com に変更する。

const firebaseConfig = {
  apiKey: "<api-key>",
  authDomain: "example.com",
  // 以下略
}

※ここも実際には環境変数を使うことになると思う

Vercel

Next.js で環境変数を使っている箇所を変更した場合、Vercel の Environment Variables を忘れず変更する。


以上で対応完了なのでデプロイし、Firefox などのログインがブロックされていたブラウザでログインできるか確認する。

ログインできなかったら Content Security Policy のエラーが出たりしていないか確認して対応する。
(私の場合、設定を変更してデプロイしなおしても反映されなかったりしたが、何回かリロードしたら反映された)

以上