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

如何用Next-Auth结合Fetch动态携带Token发送请求?

解决Next-Auth + Fetch携带Token请求的问题

一、先解决Session无法获取Token和user的问题

1. 检查Next-Auth配置文件

确保在pages/api/auth/[...nextauth].js(或App Router下的app/api/auth/[...nextauth]/route.js)中,正确通过jwt和session回调把token和用户信息同步到session对象:

// App Router版本示例
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

const authOptions = {
  providers: [
    CredentialsProvider({
      async authorize(credentials) {
        // 调用后端登录接口,获取用户信息和token
        const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/seller/login`, {
          method: "POST",
          body: JSON.stringify(credentials),
          headers: { "Content-Type": "application/json" },
        });
        const userData = await res.json();
        
        if (res.ok && userData) {
          // 必须返回包含token的对象,供后续jwt回调使用
          return {
            id: userData.id,
            name: userData.name,
            accessToken: userData.accessToken
          };
        }
        return null;
      },
    }),
  ],
  session: { strategy: "jwt" }, // 强制用JWT策略,避免数据库依赖
  callbacks: {
    async jwt({ token, user }) {
      // 用户登录时,将接口返回的token和用户信息合并到JWT
      if (user) {
        token.accessToken = user.accessToken;
        token.user = { id: user.id, name: user.name };
      }
      return token;
    },
    async session({ session, token }) {
      // 把JWT中的数据同步到session,让前端可以直接获取
      session.accessToken = token.accessToken;
      session.user = token.user;
      return session;
    },
  },
};

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };

2. 前端正确获取Session

  • 客户端组件(Next.js 13+需加'use client'指令):
'use client';
import { useSession } from "next-auth/react";

export default function SellerDashboard() {
  const { data: session, status } = useSession();

  if (status === "loading") return <div>加载中...</div>;
  if (!session) return <div>请先登录</div>;

  // 现在可以正常获取session.accessToken和session.user
  console.log(session.accessToken, session.user);
  
  return <div>卖家后台主页</div>;
}
  • 服务器组件/API路由:用getServerSession获取Session
import { getServerSession } from "next-auth/next";
import { authOptions } from "../api/auth/[...nextauth]/route";

export async function getServerSideProps(context) {
  const session = await getServerSession(context.req, context.res, authOptions);
  if (!session) {
    return { redirect: { destination: "/login" } };
  }

  // 服务器端携带Token请求后端
  const res = await fetch(`${process.env.API_URL}/seller/orders`, {
    headers: {
      Authorization: `Bearer ${session.accessToken}`,
    },
  });
  const orders = await res.json();

  return { props: { orders } };
}

二、解决手动带Token返回401的问题

按以下步骤排查:

  • 检查Token格式:后端通常要求请求头为Authorization: Bearer <你的Token>,不要漏写Bearer前缀
  • 验证Token有效性:用jwt.io解析Token,查看exp字段是否过期,以及签名密钥是否和后端一致
  • 检查后端CORS配置:Node.js后端必须允许携带Authorization头,示例配置:
const cors = require('cors');
app.use(cors({
  origin: process.env.FRONTEND_URL, // 比如http://localhost:3000
  credentials: true,
  allowedHeaders: ['Content-Type', 'Authorization'] // 必须包含Authorization
}));
  • 核对后端Token验证逻辑:确认后端是从Authorization头中提取Token,并且用正确的密钥解析,没有把accessToken和refreshToken搞混

三、封装带Token的Fetch工具函数

避免每次手动拼接请求头,封装一个复用函数:

// utils/fetchWithToken.js
'use client';
import { useSession } from "next-auth/react";

export async function fetchWithToken(url, options = {}) {
  const { data: session } = useSession();
  if (!session?.accessToken) {
    throw new Error('未登录,无访问权限');
  }

  const mergedHeaders = {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${session.accessToken}`,
    ...options.headers,
  };

  return fetch(url, {
    ...options,
    headers: mergedHeaders,
  });
}

内容的提问来源于stack exchange,提问作者Xyz.WebDeveloper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:31:17