Firebase Auth会话Cookie未设置:Next.js服务端组件无法获取用户
解决Next.js服务端组件获取Firebase Auth用户信息的问题
首先明确:你需要手动显式设置__session Cookie,Firebase Auth不会自动帮你完成这一步。教程里的代码是基于已有Cookie设置的前提,所以你得补全这部分流程,具体步骤如下:
1. 客户端登录后,将ID Token发送到后端设置Cookie
用户在客户端组件通过Firebase Auth登录成功后,获取ID Token,调用Next.js API路由传递Token,由后端验证后设置__session Cookie。
客户端代码示例:
import { getAuth, signInWithEmailAndPassword, getIdToken } from "firebase/auth"; async function handleLogin(email, password) { const auth = getAuth(); const userCredential = await signInWithEmailAndPassword(auth, email, password); const idToken = await getIdToken(userCredential.user); // 调用API路由设置Cookie await fetch("/api/set-session", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ idToken }), }); }
2. 创建API路由验证Token并设置__session Cookie
先在项目中初始化Firebase Admin SDK:
// lib/firebase-admin.js import { initializeApp, getApps, cert } from "firebase-admin/app"; import { getAuth } from "firebase-admin/auth"; if (!getApps().length) { initializeApp({ credential: cert(process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT), }); } export const adminAuth = getAuth();
然后编写app/api/set-session/route.js路由文件:
import { adminAuth } from "@/lib/firebase-admin"; import { cookies } from "next/headers"; export async function POST(request) { const { idToken } = await request.json(); try { // 验证ID Token,设置Cookie有效期(示例为1小时) const expiresIn = 60 * 60 * 1000; const sessionCookie = await adminAuth.createSessionCookie(idToken, { expiresIn }); // 设置安全Cookie cookies().set("__session", sessionCookie, { httpOnly: true, secure: process.env.NODE_ENV === "production", sameSite: "strict", maxAge: expiresIn / 1000, path: "/", }); return new Response(JSON.stringify({ status: "success" }), { status: 200 }); } catch (error) { return new Response(JSON.stringify({ error: "Invalid token" }), { status: 401 }); } }
3. 服务端组件中获取并验证__session Cookie
现在可以在服务端组件中获取Cookie并验证,拿到用户信息:
// 服务端组件示例 import { adminAuth } from "@/lib/firebase-admin"; async function getServerUser() { const { cookies } = await import("next/headers"); const sessionCookie = cookies().get("__session")?.value; if (!sessionCookie) return null; try { const decodedClaims = await adminAuth.verifySessionCookie(sessionCookie, true); // 通过UID获取完整用户信息 const user = await adminAuth.getUser(decodedClaims.uid); return user; } catch (error) { // Cookie无效,返回null触发重新登录逻辑 return null; } } export default async function ServerComponent() { const user = await getServerUser(); if (!user) { return <div>请先登录</div>; } return <div>当前登录用户:{user.email}</div>; }
关于authjs.session-token的说明
这个Cookie和你的当前需求无关,大概率是项目依赖残留、之前测试Next-Auth留下的,或者第三方包附带的,直接忽略即可。
内容的提问来源于stack exchange,提问作者RMP
相关产品推荐
相关产品推荐

