NextAuth谷歌登录后Session返回空对象问题求助
NextAuth Google登录跳转与Session为空问题解决
问题原因拆解
1. 返回URL时Session为空的原因
当你在signIn回调中直接返回URL字符串时,NextAuth会跳过后续的会话持久化流程——它只执行跳转操作,不会触发jwt和session回调来生成并存储用户会话。这就导致后续session回调里拿不到用户数据,自然返回的user对象为空。
2. 返回true时跳回登录页的原因
返回true后,NextAuth会正常完成会话创建流程(生成jwt、同步session),但默认会跳转到你配置的callbackUrl(如果没手动配置,默认是发起登录请求的页面,通常是登录页),所以才会出现Session正常但跳回登录页的情况。
正确实现方案
核心思路是:先让NextAuth完成会话创建(signIn回调返回true),把用户是否存在的状态存入会话,再通过登录回调页或Middleware来完成跳转。
步骤1:配置NextAuth回调,存储用户状态
修改[...nextauth].js文件,在signIn回调中调用后端接口判断用户,将结果存入token和session:
import NextAuth from "next-auth"; import GoogleProvider from "next-auth/providers/google"; export default NextAuth({ providers: [ GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, }), ], callbacks: { async signIn({ user }) { // 调用后端接口检查用户是否存在 const checkRes = await fetch(`${process.env.NEXT_PUBLIC_API_BASE}/check-user`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: user.email }), }); const { exists } = await checkRes.json(); // 将用户存在状态附加到user对象,供jwt回调使用 user.exists = exists; // 返回true,让NextAuth完成会话创建流程 return true; }, async jwt({ token, user }) { // 首次登录时,将用户信息存入token if (user) { token.email = user.email; token.exists = user.exists; } return token; }, async session({ session, token }) { // 将token中的信息同步到session,供前端使用 session.user.email = token.email; session.user.exists = token.exists; return session; }, }, // 指定登录成功后的默认回调页,后续在这里处理跳转 callbackUrl: "/auth/callback", });
步骤2:创建登录回调页处理跳转
在pages/auth/callback.js中,根据session中的用户状态完成跳转:
import { useSession } from "next-auth/react"; import { useEffect } from "react"; import { useRouter } from "next/router"; export default function AuthCallback() { const { data: session, status } = useSession(); const router = useRouter(); useEffect(() => { // 会话验证完成后,根据用户存在状态跳转 if (status === "authenticated") { router.push(session.user.exists ? "/" : "/apply-form"); } }, [status, session, router]); return <div>登录验证中...</div>; }
可选:用Middleware实现无UI跳转(Next.js 12+)
如果不想显示中间跳转页,可以用Next.js Middleware直接处理:
创建middleware.js文件:
import { getToken } from "next-auth/jwt"; import { NextResponse } from "next/server"; export async function middleware(req) { const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET }); const currentPath = req.nextUrl.pathname; // 仅在登录回调页触发跳转逻辑 if (currentPath === "/auth/callback" && token) { return NextResponse.redirect( new URL(token.exists ? "/" : "/apply-form", req.url) ); } return NextResponse.next(); } // 指定匹配的路由 export const config = { matcher: ["/auth/callback"], };
内容的提问来源于stack exchange,提问作者Sb Zakaria
相关产品推荐
相关产品推荐

