Next-Auth v4+Next13 App目录下OAuth登录后useSession数据未定义求助
问题:Next-Auth v4 + Next.js 13 App目录下OAuth登录重定向后useSession返回data为undefined
我在使用Next-Auth v4结合Next.js 13+的App目录实现OAuth认证时,执行signIn回调并重定向到注册页面后,调用const {data} = useSession()得到的data始终是undefined,相关代码如下:
Next-Auth回调配置:
callbacks: { async signIn({ user, account, profile, email, credentials }) { try { const check = await checkToken({ provider: account?.provider || '', id_token: account?.id_token || '', access_token: account?.access_token || '', }); return check === 'login' || `/user/${check}`; } catch (e) { if (e instanceof AxiosError) { if (e.response?.data.error.code === 4029) alert(e.message); return true; } } return true; }, async redirect({ url, baseUrl }) { return url; }, async session({ session, user, token }) { const newSession = { ...session, accessToken: token.accessToken, user: { ...user, id: token.id, }, }; return newSession; }, async jwt({ token, user, account, profile }) { if (account) { token.accessToken = account.access_token; token.id = profile?.name; } return token; }, },
SessionProvider组件:
const Sesstion = ({ children }: Props) => { return <SessionProvider>{children}</SessionProvider>; };
我查阅了官方文档,但仍无法解决该问题。
可能的原因及解决方法
1. 修正SessionProvider的全局覆盖与拼写问题
在Next.js 13+的App目录中,SessionProvider必须包裹整个应用的根布局才能全局生效,同时注意你的组件拼写错误:Sesstion → Session。
修改步骤:
- 修正组件名称为
Session - 在
app/layout.tsx中导入并包裹所有子内容:
// app/layout.tsx import { Session } from '@/components/Session'; // 替换为你的组件实际路径 export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="zh-CN"> <body> <Session>{children}</Session> </body> </html> ); }
2. 调整signIn回调的重定向逻辑
signIn回调直接返回路径字符串时,会触发即时重定向,但此时会话可能还未完成JWT的生成与存储,导致重定向后的页面无法读取session数据。应改为先允许登录,再在redirect回调中处理跳转:
callbacks: { async signIn({ user, account, profile, email, credentials }) { try { const check = await checkToken({ provider: account?.provider || '', id_token: account?.id_token || '', access_token: account?.access_token || '', }); // 将重定向路径存入account,后续通过jwt回调写入token if (check !== 'login') { account.customRedirectPath = `/user/${check}`; } return true; } catch (e) { if (e instanceof AxiosError) { if (e.response?.data.error.code === 4029) alert(e.message); return true; } } return true; }, async redirect({ url, baseUrl, token }) { // 从token中读取自定义重定向路径 if (token?.customRedirectPath) { return `${baseUrl}${token.customRedirectPath}`; } return url.startsWith(baseUrl) ? url : baseUrl; }, async jwt({ token, user, account, profile }) { if (account) { token.accessToken = account.access_token; token.id = profile?.name; // 保存重定向路径到token if (account.customRedirectPath) { token.customRedirectPath = account.customRedirectPath; } } return token; }, // ...其他回调 }
3. 修正session回调的参数依赖问题
App目录下Next-Auth默认使用JWT会话策略,session回调中的user参数可能不会直接传入,依赖该参数会导致session数据异常,应改为基于token和session原有数据扩展:
async session({ session, token }) { const newSession = { ...session, accessToken: token.accessToken, user: { ...session.user, // 基于session自带的user对象扩展 id: token.id, }, }; return newSession; }
4. 确保useSession在客户端组件中使用
在App目录中,使用useSession的组件必须添加'use client'指令标记为客户端组件,否则无法读取会话数据:
// app/user/[id]/page.tsx 'use client'; // 必须添加该指令 import { useSession } from 'next-auth/react'; export default function RegisterPage() { const { data: session, status } = useSession(); if (status === 'loading') { return <div>加载中...</div>; } return ( <div> {session ? ( <p>当前用户ID: {session.user.id}</p> ) : ( <p>未获取到会话数据</p> )} </div> ); }
5. 确认JWT会话策略配置
检查你的Next-Auth配置文件,确保使用JWT策略(App目录推荐):
// app/api/auth/[...nextauth]/route.ts import NextAuth from 'next-auth'; import { authOptions } from '@/lib/auth'; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
authOptions中需明确配置:
export const authOptions = { providers: [/* 你的OAuth服务商配置 */], session: { strategy: 'jwt', // 确保启用JWT策略 }, callbacks: { /* 你的回调配置 */ }, };
内容的提问来源于stack exchange,提问作者song s
相关产品推荐
相关产品推荐

