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

Next.js中间件获取URL查询Token异常:多次输出且出现Null

解决Next.js中间件处理重置密码路由时因静态资源请求导致Token为空崩溃的问题

问题描述

我在做重置密码功能时,给用户邮箱发了带Token查询参数的链接(比如http://localhost:3000/auth/newPassword?token=xxx),想用中间件在用户访问该路由前验证Token有效性。但运行后发现中间件会三次打印请求URL,其中第二次请求是http://localhost:3000/_next/static/chunks/pages/auth/newPassword.js?ts=1667894719054——这个请求不带Token参数,导致获取到的Token为null,最终触发jsonwebtoken的verify方法报错,项目直接崩溃。

当前使用的中间件代码:

import { NextResponse, NextRequest } from "next/server";
import { verify } from "jsonwebtoken";

const secret = process.env.JWT_SECRET!;

export default async function middleware(req: NextRequest) {
  const url = req.url;
  const token = await req.nextUrl.searchParams.get("token")!;
  const cookies = req.cookies;
  if (url.includes("/auth/newPassword")) {
    console.log(url);

    if (token === undefined) {
      return NextResponse.redirect("http://localhost:3000/auth/signin");
    }
    try {
      verify(token, secret);
      return NextResponse.next();
    } catch (e) {
      return NextResponse.redirect("http://localhost:3000/auth/signin");
    }
  }
}

解决方案

关键修改点:

  • 过滤Next.js的静态资源请求,只对页面路由做Token验证
  • 完善Token空值判断,同时避免非空断言引发的强制类型错误

修改后的中间件代码:

import { NextResponse, NextRequest } from "next/server";
import { verify } from "jsonwebtoken";

const secret = process.env.JWT_SECRET!;

export default async function middleware(req: NextRequest) {
  const url = req.url;
  
  // 直接放行静态资源请求,不做Token验证
  if (url.includes("_next/static/")) {
    return NextResponse.next();
  }

  // 去掉不必要的await和非空断言,保留原始返回值
  const token = req.nextUrl.searchParams.get("token");
  
  if (url.includes("/auth/newPassword")) {
    console.log(url);

    // 同时处理token为null或undefined的情况
    if (!token) {
      // 使用相对路径跳转,避免硬编码域名
      return NextResponse.redirect(new URL("/auth/signin", req.url));
    }
    try {
      verify(token, secret);
      return NextResponse.next();
    } catch (e) {
      return NextResponse.redirect(new URL("/auth/signin", req.url));
    }
  }

  // 其他路由直接放行
  return NextResponse.next();
}

原因说明

  1. Next.js加载页面时会自动请求对应的静态chunk文件(_next/static/chunks/下的JS),这些请求不会携带页面路由的查询参数,所以Token必然为空;
  2. 原代码用了非空断言!,强制把get("token")的结果当成非空值,当Token实际为null时,直接传入verify就会报错;
  3. 原代码只判断了token === undefined,但searchParams.get()在参数不存在时返回的是null,不是undefined,导致空值没被拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:00:59