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

Next.js Middleware路由异常:isAuth与isAdmin函数失效求助

问题根源

Next.js Middleware 运行在服务器端(Edge Runtime),而 sessionStorage 是浏览器专属的存储 API,服务器环境中根本不存在这个对象——这就是 isAuth 和 isAdmin 函数完全失效的核心原因,它们永远拿不到 authToken,返回结果始终为 false。

解决方案

要让服务器端的 Middleware 能获取到用户认证信息,必须把 Token 存在HTTP Cookie中(Cookie 会在每次请求时自动携带到服务器),同时修改校验函数从请求的 Cookie 中读取 Token。

1. 修改 Middleware 代码

将请求对象传递给校验函数,让函数能读取请求中的 Cookie:

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { isAuth } from "@/utils/isAuth";
import { isAdmin } from "@/utils/isAdmin";

export function middleware(request: NextRequest) {
  const auth = isAuth(request);

  if (!auth) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  const admin = isAdmin(request);

  if (!admin) {
    return NextResponse.redirect(new URL("/posts", request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: "/dashboard",
};

2. 重写 isAuth 函数

从请求的 Cookie 中读取 Token:

import { NextRequest } from "next/server";

export function isAuth(request: NextRequest) {
  // 从请求Cookie中获取authToken
  const authToken = request.cookies.get("authToken")?.value;
  // 存在Token则返回true,否则false
  return !!authToken;
}

3. 重写 isAdmin 函数

同样从 Cookie 取 Token,并且建议用 jwt.verify 代替 decode(同时验证 Token 签名的有效性,防止篡改):

import jwt from "jsonwebtoken";
import { NextRequest } from "next/server";

export function isAdmin(request: NextRequest) {
  const authToken = request.cookies.get("authToken")?.value;

  if (!authToken) return false;

  try {
    // 验证Token并解码,需传入你的JWT密钥
    const decodedToken = jwt.verify(authToken, process.env.JWT_SECRET!) as { role?: string };
    
    return decodedToken.role === "admin" || decodedToken.role === "developer";
  } catch (error) {
    // Token验证失败或解码出错,返回false
    return false;
  }
}

4. 登录时设置 Cookie(关键步骤)

登录成功后,要把生成的 JWT Token 存入 Cookie,而不是 sessionStorage。示例登录 API 路由代码:

// app/api/login/route.ts
import { NextResponse } from "next/server";
import jwt from "jsonwebtoken";

export async function POST(request: Request) {
  // 这里替换成你的用户校验逻辑(比如验证账号密码)
  const user = { id: 123, role: "admin" };

  // 生成JWT Token
  const token = jwt.sign(user, process.env.JWT_SECRET!, { expiresIn: "1d" });

  // 创建响应并设置Cookie
  const response = NextResponse.json({ success: true });
  response.cookies.set("authToken", token, {
    httpOnly: true, // 禁止前端JS读取,防范XSS攻击
    secure: process.env.NODE_ENV === "production", // 生产环境强制HTTPS传输
    sameSite: "strict", // 防范CSRF攻击
    maxAge: 86400, // Cookie有效期1天(秒)
    path: "/", // 全站所有路由都能访问该Cookie
  });

  return response;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:52:18