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

Next.js+NextAuth:Server Action中获取JWT调用外部后端方案咨询

解决NextAuth在Server Action/Server Component中获取Token调用外部后端的方案

一、Server Action中获取Token的替代方法

Next.js 13+的Server Action里没有直接的req对象,但可以用NextAuth提供的getServerSession方法获取会话信息,进而拿到Token:

import { getServerSession } from "next-auth/next";
import { authOptions } from "@/app/api/auth/[...nextauth]/route";

export async function fetchExternalData() {
  const session = await getServerSession(authOptions);
  if (!session?.user?.accessToken) {
    throw new Error("用户未授权");
  }

  // 调用外部后端
  const response = await fetch("https://your-external-api.com/data", {
    method: "GET",
    headers: {
      "Authorization": `Bearer ${session.user.accessToken}`
    }
  });

  if (!response.ok) {
    throw new Error("请求外部服务失败");
  }

  return response.json();
}

注意:需要在authOptions的session配置里设置strategy: "jwt",并在jwt回调中把accessToken存入token,这样getServerSession才能拿到:

// [...nextauth]/route.ts
export const authOptions: NextAuthOptions = {
  providers: [/* 你的登录提供商 */],
  session: {
    strategy: "jwt",
  },
  callbacks: {
    async jwt({ token, user }) {
      // 首次登录时把用户的accessToken存入token
      if (user) {
        token.accessToken = user.accessToken; // 按需调整字段名,匹配你的登录流程
      }
      return token;
    },
    async session({ session, token }) {
      // 把token里的accessToken同步到session
      session.user.accessToken = token.accessToken as string;
      return session;
    },
  },
};

二、Server Component中调用外部后端的方案

Server Component本身运行在服务器端,同样可以用getServerSession获取Token,直接发起请求,完全不会暴露Token给客户端:

import { getServerSession } from "next-auth/next";
import { authOptions } from "@/app/api/auth/[...nextauth]/route";

export default async function ServerComponent() {
  const session = await getServerSession(authOptions);
  let data = null;

  if (session?.user?.accessToken) {
    const response = await fetch("https://your-external-api.com/data", {
      headers: {
        "Authorization": `Bearer ${session.user.accessToken}`
      }
    });
    data = await response.json();
  }

  return (
    <div>
      {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : <p>未登录或无权限</p>}
    </div>
  );
}

三、其他进阶方案

  • 封装API路由作为中间层:如果需要复用外部后端调用逻辑,可以创建内部API路由(如/api/external-proxy),在路由里通过getToken({ req })获取Token,再转发请求到外部服务。Server Action或Server Component只需调用这个内部路由即可:
// app/api/external-proxy/route.ts
import { getToken } from "next-auth/jwt";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
  const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
  if (!token?.accessToken) {
    return NextResponse.json({ error: "未授权" }, { status: 401 });
  }

  const externalResponse = await fetch("https://your-external-api.com/data", {
    headers: {
      "Authorization": `Bearer ${token.accessToken}`
    }
  });

  const data = await externalResponse.json();
  return NextResponse.json(data);
}

在Server Component/Action中调用:

const response = await fetch("/api/external-proxy");
const data = await response.json();
  • Middleware统一处理:如果多个请求都需要携带Token,可以在Middleware中验证会话,把Token存入请求头,后续API路由或Server组件直接从请求头获取即可,该方案更适合批量API路由场景。

内容的提问来源于stack exchange,提问作者Spongi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:02:47