Next.js 13 App目录下如何通过NextAuth在客户端获取currentUser
解决Next.js 13 App目录下客户端获取currentUser的问题
你当前的getCurrentUser依赖getServerSession,这个方法是服务端专属API,只能在Server Components、API路由、Server Actions这类服务端环境运行,客户端组件直接调用会因为缺少服务端上下文而失效。下面提供两种可行的客户端获取方案:
方案一:useSession钩子 + 客户端API请求
利用NextAuth的useSession在客户端拿到基础会话信息,再通过API路由获取完整用户数据:
- 新建API路由
app/api/current-user/route.ts,复用你现有的用户查询逻辑:
import { NextResponse } from 'next/server'; import getCurrentUser from '@/app/hooks/getCurrentUser'; export async function GET() { const user = await getCurrentUser(); return NextResponse.json(user); }
- 在客户端组件中调用该API:
'use client'; import { useSession } from 'next-auth/react'; import { useEffect, useState } from 'react'; export default function ClientUserInfo() { const { data: session, status } = useSession(); const [currentUser, setCurrentUser] = useState(null); useEffect(() => { const fetchUser = async () => { if (status === 'authenticated') { const res = await fetch('/api/current-user'); const user = await res.json(); setCurrentUser(user); } else { setCurrentUser(null); } }; fetchUser(); }, [status]); if (status === 'loading') return <div>加载中...</div>; if (!currentUser) return <div>未登录</div>; return <div>当前用户:{currentUser.name}</div>; }
- 确保根布局中添加
SessionProvider(app/layout.tsx):
'use client'; import { SessionProvider } from 'next-auth/react'; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="zh-CN"> <body> <SessionProvider>{children}</SessionProvider> </body> </html> ); }
方案二:Server Component传数据给Client Component
在父级Server Component中获取用户数据,再通过props传递给子级客户端组件:
- 父级Server Component(比如
app/page.tsx):
import getCurrentUser from '@/app/hooks/getCurrentUser'; import ClientUserInfo from './client-user-info'; export default async function Home() { const currentUser = await getCurrentUser(); return ( <main> <ClientUserInfo currentUser={currentUser} /> </main> ); }
- 子级客户端组件(
app/client-user-info.tsx):
'use client'; type Props = { currentUser: { name: string; email: string } | null; }; export default function ClientUserInfo({ currentUser }: Props) { if (!currentUser) return <div>未登录</div>; return <div>当前用户:{currentUser.name}</div>; }
内容的提问来源于stack exchange,提问作者onnedaay
相关产品推荐
相关产品推荐

