You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 09:34:54