Next.js部署至Firebase Hosting后Middleware无法读取Cookie的问题求助
大家好,我遇到了一个困扰很久的问题:我的Next.js 15.1.3项目在本地开发模式下运行完全正常,但部署到Firebase Hosting后,Middleware里就无法读取到设置好的Cookie了,想请教下有没有朋友遇到过类似情况,或者能帮我排查下问题出在哪里?
问题场景说明
用户登录时,我会通过Firebase Auth获取ID Token和Refresh Token,然后调用服务端Action setToken() 在服务端设置HttpOnly Cookie。本地开发时,Middleware能正常读取这些Cookie并做路由校验;但部署到Firebase生产环境后,GET请求的Middleware里完全读不到Cookie,只有POST请求能正常读取。
相关代码细节
1. 前端登录状态监听与服务端Action调用
我在组件的useEffect里监听Firebase Auth的状态变化,当用户登录时获取Token并调用setToken服务端Action:
useEffect(() => { const unsubscribe = auth.onAuthStateChanged(async (user) => { setCurrentUser(user ?? null); if (user) { // get the token and refresh token const tokenResult = await user.getIdTokenResult(); const token = tokenResult.token; const refreshToken = user.refreshToken; if (token && refreshToken) { // Call server action with token and refresh token await setToken({token, refreshToken}); } const claims = tokenResult.claims; setCustomClaims(claims ?? null); } else { await removeToken(); } }); return () => unsubscribe(); }, []);
2. 服务端Action setToken() 实现
这个Action的作用是验证Token合法性后,为管理员用户设置服务端Cookie:
export const setToken = async ({ token, refreshToken, }: { token: string; refreshToken: string; }) => { try { const verifiedToken = await auth.verifyIdToken(token); if (!verifiedToken) { return; } const userRecord = await auth.getUser(verifiedToken.uid); if (process.env.ADMIN_EMAIL === userRecord.email) { auth.setCustomUserClaims(verifiedToken.uid, { role: 'admin', }); // this is where the cookies are set server side const cookieStore = await cookies(); cookieStore.set('firebaseAuthToken', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', }); cookieStore.set('firebaseAuthRefreshToken', refreshToken, { httpOnly: true, secure: process.env.NODE_ENV === 'production', }); } } catch (e) { console.log(e); } };
3. Middleware 路由校验代码
这部分是Cookie读取和路由拦截的逻辑,生产环境下GET请求进来时token始终为null:
export async function middleware(request: NextRequest) { const pathname = request.nextUrl.pathname; if (request.method === 'POST') { return NextResponse.next(); } const cookieStore = await cookies(); const token = cookieStore.get('firebaseAuthToken')?.value; if (pathname !== '/login') { if (!token) { return NextResponse.redirect(new URL('/login', request.url)); } const decodedToken = decodeJwt(token); if (!isAutherized(decodedToken.role as string | undefined)) { return NextResponse.redirect(new URL('/login', request.url)); } return NextResponse.next(); } else { if (token) { const decodedToken = decodeJwt(token); if (!isAutherized(decodedToken.role as string | undefined)) { return NextResponse.next(); } return NextResponse.redirect(new URL('/messages', request.url)); } return NextResponse.next(); } }
额外发现
本地开发环境中,不管是GET还是POST请求,Middleware都能正常读取到Cookie;但部署到Firebase Hosting后,只有POST请求能读到Cookie,GET请求里cookieStore.get('firebaseAuthToken')返回的始终是undefined。
项目依赖配置
部署到Firebase时我必须使用firebase-admin@^12.0.0,下面是完整的package.json内容:
{ "private": true, "scripts": { "dev": "next dev --turbopack", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "@hookform/resolvers": "^3.9.1", "@radix-ui/react-alert-dialog": "^1.1.4", "@radix-ui/react-aspect-ratio": "^1.1.1", "@radix-ui/react-avatar": "^1.1.2", "@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-label": "^2.1.1", "@radix-ui/react-navigation-menu": "^1.2.3", "@radix-ui/react-radio-group": "^1.2.2", "@radix-ui/react-select": "^2.1.4", "@radix-ui/react-separator": "^1.1.1", "@radix-ui/react-slider": "^1.2.2", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-toast": "^1.2.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "firebase": "^11.1.0", "firebase-admin": "^12.0.0", "jose": "^5.9.6", "lucide-react": "^0.469.0", "next": "15.1.3", "react": "^19.0.0", "react-dom": "^19.0.0", "react-hook-form": "^7.54.2", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", "uuid": "^11.0.3", "zod": "^3.24.1" }, "devDependencies": { "@eslint/eslintrc": "^3", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", "eslint": "^9", "eslint-config-next": "15.1.3", "postcss": "^8", "tailwindcss": "^3.4.1", "typescript": "^5" } }
有没有朋友能帮我分析下问题根源?是Cookie的设置参数(比如domain、path、SameSite)有遗漏,还是Firebase Hosting的部署配置有什么特殊要求?感谢大家的帮助!
备注:内容来源于stack exchange,提问作者Aimn Blbol

