如何修改Next.js中间件以适配两个路由组?
解决Next.js双路由组的中间件认证重定向问题
问题说明
项目采用Next.js App Router,包含两个路由组:
(auth):存放认证页面(如/sign-in)(root):包含首页/、仪表盘/dashboard及其他需认证的页面
需求:未携带accessToken Cookie的请求,需重定向到/sign-in;但现有中间件对(root)组内的路由(如/dashboard)无效。
现有代码问题
- Matcher正则错误:原正则排除了
auth前缀路径,但(auth)路由组的实际URL不带auth前缀(如/sign-in),导致认证页面未被正确排除,同时规则未准确覆盖(root)组的所有路径。 - 中间件逻辑缺陷:仅排除了首页
/,未排除认证页面/sign-in,可能引发重定向循环;且遗漏了对(root)组其他路由的验证。
修改后的代码
import { cookies } from 'next/headers'; import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server'; export function middleware(request: NextRequest) { const accessToken = cookies().get('accessToken'); const currentPath = request.nextUrl.pathname; // 定义无需认证的路径 const publicPaths = ['/sign-in']; // 未登录且访问需认证路径时,重定向到登录页 if (!accessToken && !publicPaths.includes(currentPath)) { return NextResponse.redirect(new URL('/sign-in', request.url)); } } export const config = { matcher: [ // 匹配所有路径,排除API、静态资源、图片及登录页 '/((?!api|_next/static|_next/image|.*\\.png$|sign-in).*)' ] };
关键修改点
- 调整Matcher规则:移除无效的
auth排除项,添加sign-in到排除列表,确保认证页面不触发中间件。 - 优化认证逻辑:明确定义
publicPaths数组,统一管理无需认证的页面,避免遗漏或错误判断。 - 覆盖所有需认证路径:Matcher现在会匹配
(root)组的所有路径(包括/、/dashboard等),确保未登录请求都会被拦截重定向。
额外注意事项
- 确保
middleware.ts文件位于项目根目录或src目录下(文件名应为.ts而非.tsx,Next.js不会识别.tsx后缀的中间件)。 - 若
(auth)组还有其他页面(如/sign-up),需将其添加到publicPaths数组中。
内容的提问来源于stack exchange,提问作者Kano Dekou Billy Brown
相关产品推荐
相关产品推荐

