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

NextJS 12.2+全局Middleware升级:实现Basic Auth弹窗不跳转

问题描述

我正将NextJS升级至v12.2+版本,该版本将页面级的_middleware文件改为全局middleware文件。同时官方说明中间件不再允许返回响应体。

此前在/admin/_middleware.js中的Basic Auth验证逻辑可正常弹出认证提示,但新架构下会报错“Middleware is returning a response body”。我尝试用NextResponse.rewrite改写,但无法在用户当前页面触发Basic Auth弹窗。

如何将如下旧代码改写为全局/src/middleware.js中的实现,确保用户不被跳转且未登录时弹出Basic Auth提示?

旧代码示例:

import { NextResponse } from "next/server";

import checkBasicAuth from "@utils/middleware/checkBasicAuth";

export function middleware(req) {
  if (
    checkBasicAuth(req.headers.get("authorization"), {
      username: process.env.AUTH_USERNAME,
      password: process.env.AUTH_PASSWORD,
    })
  ) {
    return NextResponse.next();
  }
  return new Response("Authentication required", {
    status: 401,
    headers: {
      "WWW-Authenticate": 'Basic realm="Secure Area"',
    },
  });
}
解决方案

在Next.js 12.2+的全局中间件中,不能直接返回new Response(),但可以通过NextResponse.rewrite结合一个空白页面来触发Basic Auth弹窗,同时保持用户当前页面的上下文:

  1. 创建触发认证的空白页面
    在pages或app目录下新建auth-required.js(或auth-required.tsx):
// pages/auth-required.js
export default function AuthRequired() {
  // 页面无需渲染内容,仅作为触发认证的载体
  return null;
}
  1. 修改全局middleware.js
    核心思路是认证失败时,重写到这个空白页面,同时设置401状态码和WWW-Authenticate头,浏览器会自动弹出认证弹窗且不会跳转页面:
// src/middleware.js
import { NextResponse } from "next/server";
import checkBasicAuth from "@utils/middleware/checkBasicAuth";

export function middleware(req) {
  const authValid = checkBasicAuth(req.headers.get("authorization"), {
    username: process.env.AUTH_USERNAME,
    password: process.env.AUTH_PASSWORD,
  });

  if (authValid) {
    return NextResponse.next();
  }

  // 生成指向空白页面的重写响应
  const authResponse = NextResponse.rewrite(new URL('/auth-required', req.url));
  // 设置触发Basic Auth的必要头信息
  authResponse.headers.set('WWW-Authenticate', 'Basic realm="Secure Area"');
  authResponse.headers.set('Content-Length', '0');
  authResponse.status = 401;

  return authResponse;
}

// 配置中间件仅对/admin路径生效,避免全局拦截
export const config = {
  matcher: '/admin/:path*',
};
  1. 关键注意点
  • 用matcher精准限定中间件作用范围,减少不必要的性能消耗
  • 重写到空白页面是为了规避“返回响应体”的限制,同时让浏览器接收401状态码触发弹窗
  • 设置Content-Length: 0确保响应体为空,符合Next.js 12.2+的规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:45:49