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

Next.js中间件重定向异常:/account路由未跳转至登录页

Next.js 会话中间器重定向异常问题

问题概述

我正在开发一个Next.js项目,已实现基于会话Cookie的中间件用于保护特定路由并完成用户重定向。但遇到了重定向不符合预期的问题,具体出现在/account路由:当用户未携带有效会话Cookie访问/account时,期望被重定向至登录页,但实际请求仍会执行并触发API调用,即便会话Cookie缺失。

中间件代码

"use server";
import { NextRequest, NextResponse } from "next/server";
import { decrypt } from "@lib/session"; // 导入decrypt用于会话验证
import { cookies } from "next/headers";

// 定义受保护和公开路由
const protectedRoutes = ["/account"];
const publicRoutes = ["/login", "/signup"];

export default async function middleware(req: NextRequest) {
  const path = req.nextUrl.pathname;
  const isProtectedRoute = protectedRoutes.includes(path);
  const isPublicRoute = publicRoutes.includes(path);

  // 获取会话Cookie
  const cookie = (await cookies()).get("session")?.value;

  // 若无会话Cookie且尝试访问受保护路由,重定向到登录页
  if (isProtectedRoute && !cookie) {
    return NextResponse.redirect(new URL("/login", req.nextUrl));
  }

  // 若路由是公开路由且用户有活跃会话,重定向到首页
  const session = cookie ? await decrypt(cookie) : null;
  if (isPublicRoute && session?.userToken) {
    return NextResponse.redirect(new URL("/", req.nextUrl));
  }

  // 一切正常则继续请求
  return NextResponse.next();
}

// 中间件配置
export const config = {
  matcher: ["/((?!api|_next/static|_next/image|.*\\.png$).*)"] // 应用中间件的路由
};

预期行为

  • 用户未携带有效会话Cookie访问/account时,中间件应将其重定向至/login。
  • 用户拥有有效会话时,中间件应允许访问/account,且不触发重定向。

问题现象

当无会话Cookie访问/account时,未被重定向至登录页,反而触发了API请求,返回如下错误:

GET /account 500 in 261ms
⨯ Error [AxiosError]: Request failed with status code 401

已尝试的解决方法

  • 检查中间件执行:在中间件中添加console.log,确认重定向逻辑已触发,但API调用仍在重定向前执行。
  • 验证Cookie处理:确认通过cookies()可正确设置和获取会话Cookie,无Cookie时中间件应处理重定向,但未生效。
  • 校验重定向逻辑:确认无会话Cookie时NextResponse.redirect()已被调用,但API仍在重定向前触发。
  • 检查前端逻辑:排查React组件是否在页面渲染前触发了意外API调用,发现请求是在服务器端中间件生效前执行的。

项目结构

src目录下包含actions、app、components、lib等子目录,app目录下有account、login、signup等路由文件夹

Axios配置

import Axios from "axios";

const axios = Axios.create({
  baseURL: "http://localhost:8000/api/app",
  headers: {
    "Content-Type": "application/json",
    "X-Requested-With": "XMLHttpRequest",
  },
  withCredentials: true,
  withXSRFToken: true,
});

export default axios;

Account页面代码

import AccountDetails from "@/components/account/AccountDetails";
import AccountSkeleton from "@components/skeletons/AccountSkeleton";
import { fetchUserData } from "@/actions/user";

export default async function Account() {
  const userData = await fetchUserData();

  if (!userData) {
    return <AccountSkeleton />;
  }

  return <AccountDetails userData={userData} />;
}

用户数据获取函数

const fetchUserData = async () => {
  const session = await getSession();
  if (!session?.userToken) {
    throw new Error("User not authenticated");
  }
  const response = await axios.get("/user/account", {
    headers: {
      Authorization: `Bearer ${session?.userToken}`,
    },
  });
  return response.data;
};

额外错误信息

Error: User not authenticated
at fetchUserData (user.ts:10:11)
at async Account (page.tsx:6:20)

Next.js配置文件(next.config.mjs)

import path from "path";

import { fileURLToPath } from "url";
import { dirname } from "path";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack(config) {
    config.resolve.alias["@"] = path.resolve(__dirname, "src");
    return config;
  },
};

export default nextConfig; 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 19:19:49