NextJS中Middleware设置授权头后,Server Action需手动添加吗?
我在开发Next.js应用时,对Middleware的工作机制有误解,以下是具体场景和问题:
编写的Middleware代码
import { NextRequest, NextResponse } from 'next/server'; export async function middleware(request: NextRequest) { const { cookies } = request; const token = cookies.get('access')?.value ?? null; request.headers.set('Authorization', `Bearer ${token}`); } export const config = { matcher: ['/:path*'] };
组件及Server Action代码
组件代码:
import { getAds } from '@actions'; import React from 'react'; const SomeComponent = () => { const fetchHandler = async () => { try { const res = await getAds(); // 这是一个Server Action console.log(res); } catch (error) { console.log('error happened', error); } } return <button onClick={fetchHandler}>Click to fetch ads</button>; }; export default SomeComponent;
Server Action(getAds)代码:
export async function getAds(): Promise<ServerAdResponse<AdSerializer>> { const res = await fetch(`External django server address/ads`, { cache: 'no-store', headers: { authorization: `Bearer ${cookies().get('access')?.value}`, // 我需要这行吗? }, }); const result = await res.json(); if (!res.ok) { throw new Error('Failed to fetch data'); } return result; }
我的问题
如果不在getAds的fetch请求里手动加Authorization头,Django服务器就会提示缺少凭证。我原本以为Middleware已经给所有请求都设置了这个头,不需要重复添加,想知道原因,以及是否必须手动添加。
原因解释
Next.js的Middleware只处理客户端发往Next.js服务器的请求,比如页面路由请求、API路由请求、静态资源请求等。而Server Action里的fetch是在Next.js服务器端发起的、去往外部Django服务器的请求,这类服务器端内部发起的请求,完全不受Middleware的影响——Middleware根本不会介入这类请求的处理流程。
另外,你当前的Middleware代码还有一个问题:只是修改了request对象的头,但没有返回NextResponse,这会导致Middleware的修改不会生效(正确做法应该是基于修改后的request创建并返回NextResponse,比如return NextResponse.next({ request })),不过就算你修复了这个问题,也依然不会影响Server Action里的外部请求。
是否必须手动添加?
是的,必须手动添加。因为Server Action里的外部请求属于服务器端发起的出站请求,Middleware的作用范围不覆盖这类请求。你可以像现在这样直接从cookies里获取token添加到请求头,也可以封装一个通用的fetch工具函数,统一处理这类外部请求的Authorization头,避免重复代码。
内容的提问来源于stack exchange,提问作者amir_70

