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

Next.js中间件问题:未带Token无法拦截非登录/注册路由

问题解决与代码优化方案

问题根源分析

  1. 中间件作用范围缺失
    原代码中config.matcher仅配置了["/"],只有访问根路径时才会触发中间件,其他路由完全绕过校验,这是无Token仍可访问页面的核心原因。
  2. 语法错误导致白名单失效
    原白名单判断代码存在两处错误:
    • 方法名拼写错误:endsWidth → endsWith
    • 逻辑或位置错误:应写成url.href.endsWith("/register") || url.href.endsWith("/login"),原写法会直接将"/register"作为判断条件,导致/login路径无法被识别为白名单。
  3. 逻辑冗余与嵌套过深
    重复编写无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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:20:29