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
相关产品推荐
相关产品推荐

