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
相关产品推荐
相关产品推荐

