第13章:Cookie制限時代のベストプラクティス:Redirectで事故らない🛡️
この章のゴールはこれ👇 **「Googleログインを redirect でやっても、Cookie/ストレージ制限が強い環境で“詰まらない”作り」**を、設計と実装とテストまで一気に固めることです💪✨ Firebase公式も「本番で全ブラウザ対応したいなら、必ず“どれかの対策オプション”を採用してね」と明言しています。(Firebase)
0) まず何が起きるの?🍪😵💫

signInWithRedirect() は内部的に クロスオリジン iframe を使って「リダイレクト前後の状態」を受け渡しします。ところが最近は、ブラウザ側が 第三者ストレージ(≒3rd party cookies/ストレージ)をブロックすることが増えて、ここが壊れやすいです。(Firebase)
しかもこれは「Chromeだけの話」じゃなくて、Safari系や「プライバシー強め設定のユーザー」でも普通に起きます🥲 (補足:Chromeの“3rd party cookie完全廃止”は、2025年4月の時点で“現状の方針を維持する(ユーザー選択中心)”へ方針転換が出ています。それでも ブロックされる環境は残るので、対策の価値は下がりません。)(Privacy Sandbox)
1) 読む(5〜8分)📚👀
- Firebase公式:Redirectが壊れる条件と、回避のためのオプション一覧(Option 1〜5)(Firebase)
- テスト観点:「3rd party cookieがブロックされた状態」をChromeで再現する考え方(Privacy Sandbox)
- (発展)FedCM:Cookie依存を減らす方向の標準API(※Firebase Auth直結というより “周辺の変化を読む” 用)(Chrome for Developers)
2) 方針決め:あなたのアプリはどの“Option”を使う?🧭✨

Firebase公式の推奨は「状況別に Option を選んでね」です。(Firebase) ここでは初心者がハマりにくい順に並べます👇
いちばんラク(おすすめ)✅
Option 1:authDomain を “今アクセスしているドメイン” に合わせる
- 特に
.web.appドメインや独自ドメインで運用するなら、この考え方が強いです。(Firebase)
次にラク✅
Option 2:可能なら Popup を使う
- Redirectが壊れる環境でも、Popupが通ることがあります(ただしPopupブロック問題あり)。(Firebase)
ちょい上級(でも強い)🧠
Option 3:/__/auth をプロキシして “同一オリジン” に寄せる(Firebase)
Option 4:Firebase Hostingを使って auth handler を同一オリジンで配る(Firebase)
Option 5:Firebase JS SDK の helper を自前ホスト(最後の手段)(Firebase)
この章の“手を動かす”では、まず **実装面の事故(ループ/結果未取得/エラーが出ても黙る)**を潰しつつ、最後に Option選択まで落とし込みます🛠️🔥
3) 手を動かす:Redirectの“戻り処理”をちゃんと作る🔁✅
3-1) クリック時:redirect開始フラグを立てる🚩

ポイント:
- redirect はページ遷移するので、**「今redirect中だよ」**を
sessionStorageに持たせると、 戻ってきたときに “結果が取れなかった” を判定しやすいです👍
// authRedirect.ts
import { auth } from "./firebase";
import { GoogleAuthProvider, signInWithRedirect } from "firebase/auth";
const provider = new GoogleAuthProvider();
export async function startGoogleRedirect() {
// ループ検知・失敗診断用のフラグ
sessionStorage.setItem("auth:redirect:attempt", String(Date.now()));
await signInWithRedirect(auth, provider);
}
3-2) アプリ起動時:getRedirectResult() を「1回だけ」実行する🧩

ポイント:
getRedirectResult()は アプリ起動時に1回だけやる(ReactならuseEffect)resultがnullのときも普通にある(redirect復帰じゃないだけ)- でも「attemptフラグがあるのに
null」なら、Cookie/ストレージ制限が疑わしい😇
// useAuthRedirectResult.ts
import { useEffect, useState } from "react";
import { auth } from "./firebase";
import { getRedirectResult } from "firebase/auth";
export function useAuthRedirectResult() {
const [checked, setChecked] = useState(false);
const [message, setMessage] = useState<string | null>(null);
useEffect(() => {
let cancelled = false;
(async () => {
try {
const result = await getRedirectResult(auth);
if (cancelled) return;
const attemptedAt = sessionStorage.getItem("auth:redirect:attempt");
if (result) {
// ✅ 成功:auth.currentUser も復元されているはず
sessionStorage.removeItem("auth:redirect:attempt");
setMessage("ログインできたよ〜!🎉");
} else if (attemptedAt) {
// ⚠️ redirectはしたっぽいのに結果が取れない
setMessage(
"ログインに戻ってきたけど、結果が取れなかったよ…🥲\n" +
"Cookie/ストレージ制限が原因かも。次の『Option診断』を見てね👇"
);
}
} catch (e) {
if (cancelled) return;
sessionStorage.removeItem("auth:redirect:attempt");
setMessage("ログインに失敗したよ…😵💫(あとで原因を表示するね)");
// ここで e をログに出す / 画面に詳細出す、など
} finally {
if (cancelled) return;
setChecked(true);
}
})();
return () => {
cancelled = true;
};
}, []);
return { checked, message };
}
3-3) UIに組み込む(超ざっくり)🖥️✨
import { startGoogleRedirect } from "./authRedirect";
import { useAuthRedirectResult } from "./useAuthRedirectResult";
export function LoginPage() {
const { checked, message } = useAuthRedirectResult();
if (!checked) return <div>確認中…⏳</div>;
return (
<div>
{message && <pre>{message}</pre>}
<button onClick={() => void startGoogleRedirect()}>
Googleでログイン(Redirect)🌈
</button>
</div>
);
}
4) 手を動かす:Option診断(“設定ミス”を最短で潰す)🧯🔍
ここが本番で一番効きます🔥 Firebase公式の Option を“自分の状況”に当てはめるチェックリストです。(Firebase)
4-1) Option 1 を採るときのチェック✅

やることは概ねこの3つ👇(公式に書いてある要点です)(Firebase)
- Firebase初期化の
authDomainを、今使うドメインに合わせる - OAuth provider側の redirect URI に
https://<authDomain>/__/auth/handlerを入れる - Firebase Console側の Authorized domains にそのドメインを入れる
ここが揃ってないと、
unauthorized-domain系で落ちたり、戻り処理が変になったりします😇
4-2) Option 4 / 5 になる目安🧠
- 「どうしてもアプリのドメインをいじれない」
- 「プロキシやHosting構成で同一オリジンに寄せたい」
- 「最悪、SDKの helper を自前で配る」
この辺は公式で選択肢として提示されています。(Firebase)
5) テスト:わざと“Cookie制限あり”で試す🧪🍪
本番前にこれをやるだけで事故が激減します🙏✨
5-1) Chrome / Edge で “3rd party cookieブロック” を再現する🧪

Chrome系は、ブロック状態をテストするための案内が用意されています。(Privacy Sandbox) (設定場所はUIが変わることがあるので、迷ったら “third-party cookies / tracking protection” で検索すると早いです🔎)
チェックすること👇
- redirect開始 → Googleログイン → 戻る
getRedirectResult()が取れる?- 取れないなら、Option 1〜5 のどれで直す?(まずOption 1を疑う)
6) ミニ課題:AIで“原因説明”をやさしくする🤖💬✨
redirect失敗時って、ユーザーに 「Cookieが〜」「ストレージが〜」って言っても伝わりにくいんですよね🥲
そこで、開発者向け/ユーザー向けに分けて、説明文をAIに作らせます✍️ Firebase AI Logic は WebからGeminiを安全寄りに呼ぶためのSDKが用意されています。(Firebase)
6-1) Firebase AI Logic(Web)の最小呼び出し例🤖✨

公式のWeb例はこんな感じです(firebase/ai から使う)(Firebase)
import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend } from "firebase/ai";
const firebaseApp = initializeApp({ /* ... */ });
// Gemini Developer API backend
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });
// 例:モデル指定(用途に合わせて)
const model = getGenerativeModel(ai, { model: "gemini-2.5-flash" });
export async function aiExplainRedirectFailure(input: {
hostname: string;
authDomain: string;
attempted: boolean;
}) {
const prompt =
"あなたはWebアプリのサポート担当です。\n" +
"Googleログイン(redirect)が失敗しました。\n" +
`状況: hostname=${input.hostname}, authDomain=${input.authDomain}, attempted=${input.attempted}\n` +
"ユーザー向けに、短く・やさしく・次に何をすればいいか、3行で案内して。";
const result = await model.generateContent(prompt);
return result.response.text();
}
なお、AIまわりはモデルの入れ替わりもあるので、公式のアナウンスは定期的に見てね📣 例:Firebase AI Logicの案内では、特定モデルのリタイア告知(2026-03-31など)も出ています。(Firebase)
7) よくある詰まりどころ(ここだけ見ても助かる)🧯😇
-
無限ループする🔁 →
signInWithRedirect()を「ログイン画面表示のたびに自動実行」してない? → この章のsessionStorageフラグ方式で“1回だけ”に制御しよ✅ -
戻ってきたのに
getRedirectResult()がnullのまま → Cookie/ストレージ制限の可能性大。Option 1(authDomain合わせ)から疑う🧠(Firebase) -
設定は合ってるはずなのに環境によって失敗 → ブラウザ側の制限を“再現テスト”して、Option見直しが最短です🧪(Privacy Sandbox)
8) チェック(できた?)✅🎯
- redirect後にアプリへ戻ってきて、1回だけ
getRedirectResult()を拾えている - attemptフラグがあるのに結果が取れないとき、ユーザーに案内が出る
- Chrome/Edgeで“Cookie制限あり”を再現しても、挙動が破綻しない(or Optionで直せる)(Privacy Sandbox)
- (発展)AIで「次にやること」をやさしく出せる🤖✨(Firebase)
必要なら、あなたの今の構成(デプロイ先URLのドメインと authDomain の値)を前提に、Option 1〜5のどれが最短で安全かを、この章の内容に沿って“決め打ち”で整理して書きますよ🧭🔥