NextJS 14中如何通过Next-Auth会话从后端API获取用户数据
解决方案:NextJS 14 结合 Next-Auth 从 SpringBoot 后端获取用户数据
方案一:客户端组件中用 useEffect + 状态管理触发请求
客户端组件不能在顶层直接写 async/await,但可以通过 useEffect 钩子触发异步请求,同时结合 useSession 获取会话里的 JWT 和 userId。
代码示例:
'use client'; import { useSession } from 'next-auth/react'; import { useEffect, useState } from 'react'; // 定义后端返回的数据结构 interface BatchData { id: string; name: string; // 其他字段根据实际需求添加 } export default function UserBatches() { const { data: session, status } = useSession(); const [batches, setBatches] = useState<BatchData[]>([]); const [loading, setLoading] = useState(false); const [error, setError] = useState<string | null>(null); useEffect(() => { const fetchBatches = async () => { // 会话未认证时直接返回 if (status !== 'authenticated' || !session) return; setLoading(true); setError(null); try { const response = await fetch(`http://你的SpringBootAPI地址/batches/${session.user.userId}`, { headers: { 'Authorization': `Bearer ${session.user.jwt}`, }, }); if (!response.ok) { throw new Error('获取批次数据失败'); } const data = await response.json(); setBatches(data); } catch (err) { setError(err instanceof Error ? err.message : '未知错误'); } finally { setLoading(false); } }; fetchBatches(); }, [session, status]); // 处理不同状态的UI展示 if (status === 'loading') return <div>加载会话信息中...</div>; if (status === 'unauthenticated') return <div>请先登录</div>; if (loading) return <div>加载用户批次数据中...</div>; if (error) return <div>错误:{error}</div>; return ( <div> <h2>你的批次</h2> <ul> {batches.map(batch => ( <li key={batch.id}>{batch.name}</li> ))} </ul> </div> ); }
方案二:用 Next.js API 路由做中间层(更安全)
把请求转发放在 Next.js 的服务器端 API 路由里,这样可以避免在客户端直接暴露请求细节,同时用 getServerSession 直接在服务端获取会话信息,无需客户端组件。
步骤1:创建 API 路由文件 app/api/batches/route.ts
import { getServerSession } from 'next-auth/next'; import { authOptions } from '../auth/[...nextauth]'; // 导入你的Next-Auth配置文件 import { NextResponse } from 'next/server'; export async function GET() { const session = await getServerSession(authOptions); // 未登录直接返回401 if (!session) { return NextResponse.json({ error: '未授权' }, { status: 401 }); } try { // 转发请求到SpringBoot后端 const response = await fetch(`http://你的SpringBootAPI地址/batches/${session.user.userId}`, { headers: { 'Authorization': `Bearer ${session.user.jwt}`, }, }); if (!response.ok) { throw new Error('调用SpringBoot API失败'); } const data = await response.json(); return NextResponse.json(data); } catch (err) { return NextResponse.json({ error: '获取批次数据失败' }, { status: 500 }); } }
步骤2:在组件中调用这个内部API
可以是服务器组件或客户端组件,这里用服务器组件示例:
export default async function UserBatches() { const response = await fetch('/api/batches'); if (!response.ok) { throw new Error('获取批次数据失败'); } const batches = await response.json(); return ( <div> <h2>你的批次</h2> <ul> {batches.map((batch: any) => ( <li key={batch.id}>{batch.name}</li> ))} </ul> </div> ); }
方案三:用 React Query 简化数据管理
如果项目频繁处理异步请求,推荐用 React Query(TanStack Query),它能自动处理缓存、加载状态、错误重试等逻辑,减少重复代码。
步骤1:安装依赖
npm install @tanstack/react-query
步骤2:在客户端组件中使用
'use client'; import { useSession } from 'next-auth/react'; import { useQuery } from '@tanstack/react-query'; interface BatchData { id: string; name: string; } // 封装请求函数 const fetchUserBatches = async (userId: string, jwt: string) => { const response = await fetch(`http://你的SpringBootAPI地址/batches/${userId}`, { headers: { 'Authorization': `Bearer ${jwt}`, }, }); if (!response.ok) { throw new Error('获取批次数据失败'); } return response.json() as Promise<BatchData[]>; }; export default function UserBatches() { const { data: session, status } = useSession(); // 使用React Query管理请求 const { data: batches, isLoading, error } = useQuery({ queryKey: ['userBatches', session?.user.userId], // 缓存键,userId变化时自动重新请求 queryFn: () => fetchUserBatches(session!.user.userId, session!.user.jwt), enabled: status === 'authenticated' && !!session, // 仅当会话有效时触发请求 }); // 状态展示 if (status === 'loading') return <div>加载会话信息中...</div>; if (status === 'unauthenticated') return <div>请先登录</div>; if (isLoading) return <div>加载用户批次数据中...</div>; if (error) return <div>错误:{(error as Error).message}</div>; return ( <div> <h2>你的批次</h2> <ul> {batches?.map(batch => ( <li key={batch.id}>{batch.name}</li> ))} </ul> </div> ); }
内容的提问来源于stack exchange,提问作者Repkins
相关产品推荐
相关产品推荐

