Next.js + Firebase Authentication + Auth.js(NextAuth.js) を組み合わせて認証・セッション管理をしていたところ、
「画面遷移やNextAuthのセッション自体は有効」なのに、「Firebaseからデータ取得」が失敗することがありました。
Auth.js(NextAuth.js)とFirebase Authのセッション切れタイミングのずれ(Firebase AuthのIDトークンの期限切れ)が原因だったようなので、その際の対応についてまとめます。
目次
原因:Auth.js(NextAuth.js)とFirebase Authのセッション切れタイミングのずれ
FirebaseのJWT(idToken)とAuth.jsのJWTについてまとめた表です。
| Firebase | Auth.js | |
|---|---|---|
| 有効期限 | 1時間 | 30日(デフォルト) |
| 用途 | Firebase API呼び出し時の認証 | アプリ内のセッション管理 |
| 署名 | Google秘密鍵 | NEXTAUTH_SECRET |
| 内容 | uid, email, firebase情報など | uid, email, name, カスタムデータなど |
こちらの表の通り、2つのJWTは有効期限が異なります。この「切れるタイミングの差」が原因で不具合が発生。
つまり、ログインから1時間経った後、「Firebaseのトークンは切れているのにAuth.jsのセッションは有効のまま」という現象が起きていたもよう。
この2つのJWTがどう認証に関わっているかについては下記参照。
Firebase Authのトークン自動更新について
👉クライアントサイド(ブラウザ)では自動更新される
Firebase SDKでは自動的にトークンの更新が行われるため、開発者が手動でリフレッシュする必要はありません。
ブラウザで.getIdToken(true)を呼び出すと、自動的にトークンがリフレッシュされます。
Loading code...
👉サーバーサイドでは自動更新されない
長時間実行されるクライアントセッションでは、サーバーサイドのトークンが期限切れになる可能性があり、通常約1時間後にユーザーがタブを再度開いた場合にページの更新が必要。
つまり、今回のようにFirebase Authentication + Auth.js(NextAuth.js) を組み合わせて認証・セッション管理をしている場合は、トークンの自動更新を実装する必要があるらしい。
解決策:リフレッシュトークンを使ってトークンを自動更新する
Firebaseのリフレッシュトークンを使うと、新しいトークンを取得することができます。
ユーザーがログインするたびに、ユーザー認証情報が Firebase Authentication バックエンドに送信され、Firebase ID トークン(JWT)および更新トークンと交換されます。Firebase ID トークンの有効期間は短く、1 時間で期限切れとなります。新しい ID トークンは、更新トークンを使用して取得できます。 更新トークンは、次のいずれかが発生した場合にのみ有効期限が切れます。
https://firebase.google.com/docs/auth/admin/manage-sessions?hl=ja
ということで、トークンの有効期限をチェックし、期限切れの場合はリフレッシュトークンを使って新しいトークンを取得する処理を実装します。
FIREBASE_TOKEN_API_KEYを取得
Google Cloud コンソール の「API とサービス」>「認証情報」にアクセス。
下記より取得した値を、環境変数FIREBASE_TOKEN_API_KEYに設定します。

続いてコードを書いていきます。
※すでにログイン機能は実装してあるものとし、必要な箇所だけ抜粋して載せます。
ログイン機能の実装は下記のサンプルコードを参照。
フロント側(ログイン処理)
Loading code...
サーバー側
有効期限のチェック、リフレッシュトークンを使って新しいトークンを取得する部分を実装します。
Loading code...
参考
ありがとうございます!!!




