コンテンツにスキップ

Firebase Auth で理解する認証トークン

og

Note: この記事は、Firebase Auth の認証トークンについて調べた際の個人的な調査メモです。体系的なガイドというよりは、学習過程で整理した内容をまとめたものになります。

このガイドでは、OAuth 2.0 / OpenID Connect における認証トークンの基礎を、Firebase Auth の特徴を中心に解説します。


概念説明
認証(Authentication)「あなたは誰か」を確認するログイン処理、パスワード検証、SAML 認証
認可(Authorization)「何ができるか」を確認する管理者権限のチェック、グループ所属確認
  • 認証が先、認可が後です。認証されていないユーザーは認可できません。

2.1 OAuth 2.0 / OpenID Connect のトークン

Section titled “2.1 OAuth 2.0 / OpenID Connect のトークン”
トークン目的内容使用場所一般的な有効期限
ID Tokenユーザー識別UID、メール、名前などフロントエンド5分〜1時間
Access Tokenリソースアクセス認可スコープ、権限バックエンド API5分〜1時間
Refresh Tokenトークン更新ランダム文字列トークン更新リクエスト7〜90日
  • 目的: 「この人は誰か」を証明する
  • 使用場所: クライアント(フロントエンド)内で消費
  • ユースケース: ユーザー名の表示、プロフィール表示、UI のパーソナライズ
  • 形式: JWT (JSON Web Token)
  • 目的: 「このリソースへのアクセス権限がある」ことを証明する
  • 使用場所: バックエンド API に送信 (Authorization: Bearer {token})
  • ユースケース: API 認可、リソースアクセス制御
  • 形式: JWT または Opaque Token
  • 目的: 新しい ID Token / Access Token を取得する
  • 使用場所: 認証サーバーへのトークン更新リクエスト
  • ユースケース: Access Token の有効期限切れ時に、再ログインなしで新しいトークンを取得
  • 形式: Opaque Token(内容は不可視)

ID Token と Access Token は、多くの場合 JWT 形式で作成されます。JWT は3つの部分で構成されています:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL...
├──────────── Header ────────────┤├────────── Payload ──────────...
{
"alg": "RS256",
"typ": "JWT"
}
  • alg: 署名アルゴリズム
  • typ: トークンタイプ
{
"iss": "https://securetoken.google.com/my-project",
"sub": "XeOK4KBxyz123abc",
"aud": "my-project",
"iat": 1704067200,
"exp": 1704070800,
"email": "user@example.com",
"firebase": {
"sign_in_provider": "password"
}
}
Claim意味
iss発行者
sub主体 = ユーザー ID (UID)
aud対象者 = プロジェクト ID
iat発行日時(タイムスタンプ)
exp有効期限(タイムスタンプ)
emailメールアドレス
  • Header と Payload を秘密鍵で署名
  • 改ざんされると署名が一致しない
  • サーバー側で verifyIdToken() などを使用して検証

4. OAuth 2.0 / OpenID Connect のフロー

Section titled “4. OAuth 2.0 / OpenID Connect のフロー”

認証が成功すると、ID Token / Access Token / Refresh Token が1つのレスポンスで同時に発行されます

{
"access_token": "eyJhbG...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "dGhpcyB...",
"id_token": "eyJhbGci..."
}
  • 認証サーバーが決定: 認証サーバー(IdP)がすべてのトークンの有効期限を設定
  • JWT の場合: exp claim に有効期限のタイムスタンプが含まれる
  • 設定可能性: プロバイダーによって異なる - 開発者が設定できるものとできないものがある
Auth ServerClientAuth ServerClientNormal Refresh FlowAPI calls can continueUser doesn't need to re-loginPrompt user to re-loginalt[Refresh Token Valid][Refresh TokenExpired/Invalid]Refresh Token Rotation (Enhanced Security)RT-1 can never be used againPrevents attacks with leaked old tokensDetect Access Token expiration(check exp claim)1POST /oauth/tokengrant_type=refresh_tokenrefresh_token={Refresh Token}2Validate Refresh Token- Check expiration- Verify not revoked3200 OKnew access_tokennew id_token(new refresh_token)4Store new tokens5401 Unauthorizedinvalid_grant6Clear stored tokens7Request refresh with RT-18Invalidate RT-19new access_tokennew id_tokennew refresh_token=RT-210
  • Access Token の有効期限が切れたら、Refresh Token を使って新しいトークンを取得
  • 1つの Refresh Token で ID Token と Access Token の両方を更新
  • ユーザーは再ログインの必要なし

5.1 ID Token が Access Token を兼ねる

Section titled “5.1 ID Token が Access Token を兼ねる”
側面標準 OAuth 2.0Firebase Auth
トークンの種類ID Token + Access TokenID Token のみ
API 認証Access Token を使用ID Token を使用
管理の複雑さ2種類を管理1種類を管理
  • Firebase では、ID Token が「認証」と「認可」の両方を処理
  • 開発者にとってシンプル - 1種類のトークンのみ管理
項目Firebase Auth
ID Token の有効期限1時間(固定、設定変更不可)
Refresh Token の有効期限実質無制限

Firebase の Refresh Token が無効化されるのは以下の場合のみ:

  • ユーザーが削除された
  • ユーザーが無効化された
  • パスワードまたはメールアドレスが変更された
  • revokeRefreshTokens(uid) が明示的に呼び出された

クライアント側 SDK(自動 Refresh Token 使用)

Section titled “クライアント側 SDK(自動 Refresh Token 使用)”
SDKユースケース
Firebase JavaScript SDK (firebase/auth)Web アプリ
Firebase iOS SDKiOS アプリ
Firebase Android SDKAndroid アプリ
Firebase Flutter SDKクロスプラットフォームアプリ
  • user.getIdToken() を呼び出すだけ - 有効期限切れの場合は自動更新
  • 開発者は Refresh Token を直接扱う必要なし

サーバー側 Admin SDK(Refresh Token 管理/無効化)

Section titled “サーバー側 Admin SDK(Refresh Token 管理/無効化)”
SDKユースケース
Firebase Admin SDK for Node.jsサーバー側
Firebase Admin SDK for Pythonサーバー側
Firebase Admin SDK for Javaサーバー側
Firebase Admin SDK for Goサーバー側
  • Refresh Token に直接アクセスできない
  • revokeRefreshTokens(uid) での無効化のみ可能

5.4 ユーザー体験とセキュリティのバランス

Section titled “5.4 ユーザー体験とセキュリティのバランス”
視点見え方
ユーザーの視点「常にログインしている」
内部動作ID Token は1時間ごとに期限切れになり、必要に応じて更新される

なぜこの設計なのか?

側面理由
短い ID Token(1時間)漏洩しても1時間後に無効になる(被害を限定)
長い Refresh Token(実質無制限)ユーザーは繰り返しログインしたくない(UX 優先)
SDK の自動更新開発者の手間なくセキュリティと UX のバランスを実現

Firebase Auth は「セキュリティ面ではトークンが1時間ごとに変わるが、UX 面ではユーザーはログイン状態を維持」を実現しています。


トークンやセッション情報の保存場所は、セキュリティと利便性のトレードオフを伴います。

ストレージ寿命タブ間共有サーバーへ自動送信JS アクセス容量
Session Storageタブを閉じるまで不可不可可能約5MB
Local Storage永続(削除するまで)可能不可可能約5MB
CookiemaxAge/expires で設定可能可能httpOnly でブロック可約4KB
IndexedDB永続可能不可可能大容量
  • 保存場所: ブラウザ(Web Storage API)
  • 寿命: タブ/ウィンドウを閉じるまで
  • スコープ: 同一タブのみ(タブ間で共有されない)
  • ユースケース: 一時的なデータ(ログイン中のみ必要な UI 状態)
// 保存
sessionStorage.setItem("key", "value");
// 取得
const value = sessionStorage.getItem("key");
// 削除
sessionStorage.removeItem("key");
  • 保存場所: ブラウザ(Web Storage API)
  • 寿命: 明示的に削除するまで永続
  • スコープ: 同一オリジン内で共有(すべてのタブ間)
  • ユースケース: ユーザー設定、キャッシュデータ
// 保存
localStorage.setItem("key", "value");
// 取得
const value = localStorage.getItem("key");
// 削除
localStorage.removeItem("key");
  • 保存場所: ブラウザ
  • 寿命: maxAge/expires で設定
  • スコープ: 同一オリジン(サブドメイン設定可能)
  • 重要な特徴: リクエストと共にサーバーへ自動送信
  • ユースケース: 認証トークン、セッション管理
// 設定(サーバー側)
response.cookies.set("name", "value", {
httpOnly: true, // JS からアクセス不可
secure: true, // HTTPS のみ
sameSite: "lax", // CSRF 保護
maxAge: 86400, // 1日(秒)
});
  • 保存場所: ブラウザ(NoSQL データベース)
  • 寿命: 明示的に削除するまで永続
  • スコープ: 同一オリジン内
  • ユースケース: 大容量データ、オフラインデータ、Firebase SDK のトークン保存

Firebase Auth SDK は ID Token と Refresh Token を IndexedDB に自動保存します:

IndexedDB: firebaseLocalStorageDb
└─ firebaseLocalStorage
└─ firebase:authUser:{apiKey}:{appName}
保存場所XSS 攻撃リスク推奨用途
Session Storage盗まれる可能性あり一時的なデータ
Local Storage盗まれる可能性あり非機密データ
Cookie (httpOnly)JS で読み取り不可認証トークン(推奨)
IndexedDB盗まれる可能性ありFirebase SDK のデフォルト
メモリのみページ遷移で失われる最も安全だが不便

名前は似ていますが、まったく異なるメカニズムです:

側面Session StorageSession Cookie
管理者ブラウザサーバーが発行 → ブラウザが保存
寿命タブを閉じるまでサーバー定義(5分〜14日)
サーバー送信手動自動
httpOnly不可(常に JS アクセス可能)設定可能
ユースケース一時的な UI 状態認証セッション管理

7. Session Cookie(Firebase Auth のコンテキスト)

Section titled “7. Session Cookie(Firebase Auth のコンテキスト)”
Section titled “7.1 Cookie の種類(一般的な定義)”

Cookie は有効期限設定に基づいて2種類に分類されます:

種類有効期限設定消えるタイミングユースケース
Session Cookieなし(maxAge/expires 未設定)ブラウザを閉じた時一時的なセッション情報
Persistent Cookieあり(maxAge/expires 設定済み)有効期限到達時ログイン状態の維持

Firebase Auth のドキュメントでは、「Session Cookie」は一般的な定義とは異なる意味を持ちます:

側面一般的な Session CookieFirebase Auth Session Cookie
定義maxAge/expires のない CookiecreateSessionCookie() で発行された Cookie
寿命ブラウザを閉じるまで5分〜14日(設定可能)
技術的な分類Session CookiePersistent Cookie
ユースケース一時的なセッションサーバー側セッション管理

つまり、Firebase の「Session Cookie」は技術的には Persistent Cookie です。

Section titled “7.3 Session Cookie の概要(Firebase のコンテキスト)”

Firebase Auth Session Cookie は、ユーザーセッションをサーバー側で管理するメカニズムです。ID Token をサーバーに送信し、Session Cookie に変換した後、以降のリクエストは Cookie ベースの認証を使用します。

側面ID Token 直接使用Session Cookie 使用
保存場所クライアント(メモリ/IndexedDB)サーバーが発行 → ブラウザ Cookie
有効期限1時間(固定)5分〜14日(設定可能)
更新クライアント SDK 自動サーバー側で明示的に更新
セキュリティJavaScript からアクセス可能httpOnly で JavaScript アクセスをブロック
Section titled “7.4 Session Cookie の作成(Firebase Admin SDK)”
// サーバー側: ID Token を受け取り Session Cookie を発行
const expiresIn = 60 * 60 * 24 * 1000; // 1日(ミリ秒)
// ID Token を検証し Session Cookie を作成
const sessionCookie = await adminAuth.createSessionCookie(idToken, {
expiresIn,
});
// レスポンスに Cookie を設定
response.cookies.set("__session", sessionCookie, {
httpOnly: true, // JavaScript からアクセス不可(XSS 保護)
secure: true, // HTTPS のみ
sameSite: "lax", // CSRF 保護
maxAge: expiresIn / 1000,
path: "/",
});
// サーバー側: Session Cookie を検証
const sessionCookie = cookies().get("__session")?.value;
const decodedClaims = await adminAuth.verifySessionCookie(sessionCookie, true);
// decodedClaims.uid, decodedClaims.email などにアクセス
フラグ効果
httpOnlytrueJavaScript からアクセス不可(XSS 保護)
securetrueHTTPS でのみ Cookie を送信
sameSitelax同一サイトリクエストでのみ Cookie を送信(CSRF 保護)
maxAgeCookie の有効期限
path/Cookie が有効なパス
項目
最小5分(300,000 ミリ秒)
最大14日(1,209,600,000 ミリ秒)
設定createSessionCookie()expiresIn オプション
Section titled “7.8 ID Token 直接使用 vs Session Cookie”
側面ID Token 直接使用Session Cookie
実装の複雑さシンプルより複雑(Cookie 管理が必要)
有効期限の柔軟性1時間固定5分〜14日で設定可能
XSS 耐性低い(JS アクセス可能)高い(httpOnly)
CSRF 耐性高い(明示的なヘッダーが必要)sameSite で保護
更新SDK 自動手動更新プロセスが必要
SSR サポート追加実装が必要Cookie 自動送信

XSS 攻撃耐性

方式保存場所XSS リスク
Session CookieCookie (httpOnly)JS で読み取り不可。ただし、Cookie は自動送信されるため、攻撃者が API を呼び出せる可能性あり
ID Token 直接使用IndexedDB / メモリlocalStorage.getItem() や IndexedDB 経由で盗まれるリスク。Firebase SDK の getIdToken() で取得可能

CSRF 攻撃耐性

方式送信方法CSRF 耐性
Session Cookie自動送信(Cookie)sameSite: 'lax' で同一サイトリクエストに制限。ただし GET リクエストでは送信される場合あり
ID Token 直接使用明示的(Authorization: BearerCSRF で自動送信されないため、より高い耐性

トークン漏洩の影響

方式有効期限緩和策
Session Cookie1日(設定可能)1日後に無効化。サーバー側で revokeRefreshTokens() を呼び出して即時無効化可能
ID Token 直接使用1時間(固定)1時間後に無効化。ただし、Refresh Token が漏洩した場合は長期的な影響(Firebase は実質無制限)

判断ポイント

側面ID Token 直接使用が適する場合Session Cookie が適する場合
XSS リスク許容度XSS リスクの低い内部ポータルXSS リスクを最小化したい
CSRF リスク許容度CSRF を完全に防止したいGET リクエストで機密操作なし
実装/保守コストシンプルさを重視セキュリティを優先
トークン漏洩の影響1時間で無効化が許容できる1日の有効期限が許容できる

参考ドキュメント:

Session Cookie を使用せず、ID Token を直接 API に送信します。Firebase SDK の自動更新機能を活用します。

特徴:

項目内容
Session Cookie不要(作成しない)
セッション更新不要(SDK が自動管理)
API 呼び出しAuthorization: Bearer {idToken} で明示的に送信
サーバー検証verifyIdToken() を使用

API 呼び出し例:

// クライアント側
const user = auth.currentUser;
const idToken = await user.getIdToken(); // 有効期限が近い場合は自動更新
const response = await fetch("/api/data", {
headers: {
Authorization: `Bearer ${idToken}`,
},
});

サーバー側検証:

// API Route
const authHeader = request.headers.get("Authorization");
const idToken = authHeader?.split("Bearer ")[1];
const decodedClaims = await adminAuth.verifyIdToken(idToken);
// decodedClaims.uid, decodedClaims.email などにアクセス

Session Cookie から移行する場合の変更点:

変更箇所内容
/api/auth/session/route.ts削除または無効化
session-refresh.ts削除(不要)
各 API RouteverifySessionCookie()verifyIdToken()
クライアント API 呼び出しAuthorization: Bearer {idToken} を追加

プロバイダーID TokenAccess TokenRefresh Token設定可能?
Firebase1時間N/A(ID Token が兼用)実質無制限不可
Google1時間1時間6ヶ月(未使用の場合)不可
Microsoft1時間1時間90日(デフォルト)可能
Auth010時間24時間2週間可能
AWS Cognito1時間1時間1日〜3650日可能
Okta設定可能設定可能設定可能可能

用語説明
Authentication本人確認
Authorization権限確認
ID Token本人証明書(JWT)
Access Tokenリソースアクセス権
Refresh Tokenトークン更新用
Session Cookieサーバー側セッション管理用 Cookie
UIDユーザー ID
Claimsトークン内の属性
JWTJSON Web Token 形式
Signature改ざん防止
IdPIdentity Provider(認証サーバー)
Custom Claims開発者が追加するカスタム属性
httpOnlyJavaScript アクセスを防ぐ Cookie フラグ
secureHTTPS 専用送信の Cookie フラグ
sameSiteCSRF 保護の Cookie フラグ
XSSCross-Site Scripting 攻撃
CSRFCross-Site Request Forgery 攻撃
Session Storageタブを閉じるとクリアされるブラウザストレージ
Local Storage永続的に保存されるブラウザストレージ
IndexedDBブラウザ内 NoSQL データベース
Persistent Cookie有効期限が設定された Cookie(期限まで永続)