Next.js中间件问题:未带Token无法拦截非登录/注册路由
问题解决与代码优化方案
问题根源分析
- 中间件作用范围缺失
原代码中config.matcher仅配置了["/"],只有访问根路径时才会触发中间件,其他路由完全绕过校验,这是无Token仍可访问页面的核心原因。 - 语法错误导致白名单失效
原白名单判断代码存在两处错误:- 方法名拼写错误:
endsWidth→endsWith - 逻辑或位置错误:应写成
url.href.endsWith("/register") || url.href.endsWith("/login"),原写法会直接将"/register"作为判断条件,导致/login路径无法被识别为白名单。
- 方法名拼写错误:
- 逻辑冗余与嵌套过深
重复编写无Token跳转逻辑,嵌套层级多,可读性差。
修复优化后的完整代码
import { NextResponse } from "next/server"; export function middleware(request) { const token = request.cookies?.get("cookieToken")?.value; const pathname = request.nextUrl.pathname; const url = request.nextUrl.clone(); // 定义无需Token校验的白名单路径 const whiteList = ["/login", "/register"]; // 白名单路径直接放行,同时处理已登录访问/login的重定向 if (whiteList.includes(pathname)) { if (pathname === "/login" && token) { url.pathname = "/"; return NextResponse.redirect(url); } return NextResponse.next(); } // 非白名单路径,无Token则重定向到登录页 if (!token) { url.pathname = "/login"; return NextResponse.redirect(url); } // 其他情况正常放行 return NextResponse.next(); } export const config = { // 匹配所有业务路由,排除静态资源和Next.js内部文件 matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"], };
优化说明
- 修正中间件作用范围:通过
matcher配置匹配所有业务路由,排除静态资源,确保所有需要校验的页面都经过中间件处理。 - 简化白名单判断:使用数组
includes方法替代后缀匹配,避免子路径误判,逻辑更直观。 - 扁平化逻辑结构:拆分独立规则判断,消除嵌套,提升代码可读性和维护性。
- 明确规则优先级:先处理白名单放行与登录态跳转,再处理非白名单的Token校验,逻辑清晰无冲突。
内容的提问来源于stack exchange,提问作者Mohamed Nabil
相关产品推荐
相关产品推荐

