NextJs14+集成AuthJs V5与Firebase邮箱密码认证遇边缘运行时错误
解决方案:NextJS14 + AuthJS V5 + Firebase邮箱密码认证
问题根源
AuthJS V5 默认在Edge Runtime中运行,而Firebase的Node.js SDK依赖Node.js核心模块(如os),Edge环境不支持这些模块,导致报错。同时,直接在服务器端调用Firebase客户端SDK的signInWithEmailAndPassword也不符合安全最佳实践(服务器不应处理用户明文密码)。
可行解决步骤
1. 强制AuthJS使用Node.js Runtime
在AuthJS的API路由文件中指定运行时为Node.js,让Firebase SDK的依赖能正常工作:
修改/src/app/api/auth/[...nextauth]/route.ts:
export const runtime = 'nodejs'; // 新增此行,指定Node.js运行时 export { GET, POST } from "@/auth";
2. 调整认证流程(安全最佳实践)
不要在服务器端直接处理密码,改为客户端先通过Firebase获取ID Token,再传给AuthJS验证:
客户端登录代码(示例:登录页面)
import { signIn } from "next-auth/react"; import { getAuth, signInWithEmailAndPassword } from "firebase/auth"; const handleLogin = async (email: string, password: string) => { const auth = getAuth(); try { // 客户端调用Firebase登录,获取用户凭证 const userCredential = await signInWithEmailAndPassword(auth, email, password); // 获取Firebase ID Token const idToken = await userCredential.user.getIdToken(); // 将ID Token传给AuthJS完成会话创建 const authResult = await signIn("credentials", { idToken, redirect: true, callbackUrl: "/dashboard", }); if (authResult?.error) { console.error("AuthJS会话创建失败:", authResult.error); } } catch (firebaseError) { console.error("Firebase登录失败:", firebaseError); } };
服务器端AuthJS配置修改(/src/auth.config.ts)
先确保已初始化Firebase Admin SDK(用于验证ID Token):
// 示例:/src/lib/firebase-admin.ts import admin from "firebase-admin"; import { getApps } from "firebase-admin/app"; if (!getApps().length) { admin.initializeApp({ credential: admin.credential.cert({ projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, clientEmail: process.env.FIREBASE_CLIENT_EMAIL, privateKey: process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/g, "\n"), }), }); } export const adminAuth = admin.auth();
然后修改AuthJS的CredentialsProvider逻辑:
import { adminAuth } from "@/lib/firebase-admin"; export default { providers: [ Credentials({ credentials: { idToken: { label: "Firebase ID Token", type: "text" }, }, async authorize(credentials) { if (!credentials?.idToken) return null; try { // 验证Firebase ID Token的有效性 const decodedToken = await adminAuth.verifyIdToken(credentials.idToken); // 获取完整用户信息 const firebaseUser = await adminAuth.getUser(decodedToken.uid); // 返回用户信息给AuthJS,用于生成会话 return { id: firebaseUser.uid, email: firebaseUser.email, name: firebaseUser.displayName, image: firebaseUser.photoURL, }; } catch (error) { console.error("ID Token验证失败:", error); return null; } }, }), ], } satisfies NextAuthConfig;
AuthJS替代方案
如果不想使用AuthJS,推荐以下适配Firebase的方案:
- 直接使用Firebase Auth + NextJS中间件:自定义中间件验证Firebase ID Token,保护路由,无需额外Auth库。
- next-firebase-auth:专门为NextJS和Firebase Auth设计的集成库,支持NextJS14,可简化会话管理流程。
内容的提问来源于stack exchange,提问作者Ann0nip
相关产品推荐
相关产品推荐

