如何在NextJS APP Route中通过NextAuth实现Axios拦截器传Token?
解决方案:NextAuth + Axios 拦截器传递 Token
问题核心
useSession 是 NextAuth 的客户端专属钩子,只能在标记为 'use client' 的组件中使用。如果在默认的服务器组件(APP Route 中未加 'use client' 的组件)里直接调用,必然会出现状态未定义的问题。下面分两种场景给出具体实现方案:
场景1:客户端组件发起 API 请求
适合在用户交互触发的前端请求中使用,通过客户端钩子获取会话并配置 Axios 拦截器。
步骤1:创建带认证的 Axios 钩子
新建 lib/axios.ts 文件:
'use client'; import axios from 'axios'; import { useSession } from 'next-auth/react'; import { useEffect } from 'react'; // 创建基础 Axios 实例 const apiClient = axios.create({ baseURL: '/api', // 替换为你的 API 基础地址 }); // 封装带会话的 Axios 钩子 export const useAxiosWithAuth = () => { const { data: session } = useSession(); useEffect(() => { // 添加请求拦截器 const interceptor = apiClient.interceptors.request.use((config) => { // 根据你的 NextAuth 会话结构调整 Token 获取路径 if (session?.user?.accessToken) { config.headers.Authorization = `Bearer ${session.user.accessToken}`; } return config; }); // 组件卸载时移除拦截器,避免内存泄漏 return () => apiClient.interceptors.request.eject(interceptor); }, [session]); return apiClient; };
步骤2:在客户端组件中使用
'use client'; import { useAxiosWithAuth } from '@/lib/axios'; const UserProfile = () => { const api = useAxiosWithAuth(); const fetchProfile = async () => { try { const res = await api.get('/user/profile'); console.log(res.data); } catch (err) { console.error('请求失败:', err); } }; return <button onClick={fetchProfile}>获取我的资料</button>; }; export default UserProfile;
场景2:服务器组件/API 路由发起请求
适合页面渲染时需要服务器端调用外部 API 的场景,使用 getServerSession 服务端方法获取会话。
步骤1:创建服务端认证 Axios 工具
新建 lib/server-axios.ts 文件:
import axios from 'axios'; import { getServerSession } from 'next-auth/next'; import { authOptions } from '@/app/api/auth/[...nextauth]/route'; // 导入你的 NextAuth 配置 export const getAuthenticatedApiClient = async () => { const session = await getServerSession(authOptions); const apiClient = axios.create({ baseURL: 'https://your-external-api.com', // 替换为目标 API 地址 }); // 注入 Token 到请求头 if (session?.user?.accessToken) { apiClient.defaults.headers.common['Authorization'] = `Bearer ${session.user.accessToken}`; } return apiClient; };
步骤2:在服务器组件中使用
import { getAuthenticatedApiClient } from '@/lib/server-axios'; // 服务器组件,无需加 'use client' export default async function Dashboard() { const api = await getAuthenticatedApiClient(); const res = await api.get('/dashboard/stats'); return <div>服务器端获取的数据:{JSON.stringify(res.data)}</div>; }
关键前置配置
确保你的 NextAuth 配置正确存储和传递 Token:
在 app/api/auth/[...nextauth]/route.ts 中添加回调:
export const authOptions = { providers: [/* 你的认证提供者(如 Google、Credentials) */], session: { strategy: 'jwt', // 推荐使用 JWT 策略 }, callbacks: { async jwt({ token, user }) { // 登录时将用户的 accessToken 存入 JWT if (user) token.accessToken = user.accessToken; return token; }, async session({ session, token }) { // 将 Token 中的 accessToken 同步到客户端会话 session.user.accessToken = token.accessToken as string; return session; }, }, };
同时,必须在根布局中添加 NextAuth 的 Provider:
'use client'; import { SessionProvider } from 'next-auth/react'; export default function RootLayout({ children }) { return ( <html lang="zh-CN"> <body> <SessionProvider>{children}</SessionProvider> </body> </html> ); }
内容的提问来源于stack exchange,提问作者Arifur Rahaman
相关产品推荐
相关产品推荐

