Next.js 14:next-intl与认证中间件共存致重定向过多错误求助
解决Next.js 14 + next-intl + 认证中间件的重定向循环问题
问题场景
开发Next.js 14项目时,使用next-intl实现本地化,同时在middleware.ts中加入认证路由保护逻辑。默认语言(无URL前缀)下功能正常,但切换语言、URL中加入语言代码后,应用触发“Too many redirects”错误并崩溃。
问题根源
认证重定向逻辑未考虑语言前缀,与next-intl的语言路由处理冲突,导致无限循环:
- 访问带语言前缀的受保护路由(如
/zh/app/explore)且无token时,认证逻辑重定向到/login,next-intl自动为其添加语言前缀(如/zh/login) - 若用户已有token,访问
/zh/login时认证逻辑会重定向到/app/explore,next-intl再次添加语言前缀形成循环;若无token,next-intl将/login转为/zh/login,认证逻辑又重定向回/login,无限循环。
解决方案
修改认证重定向逻辑,保留当前请求的语言前缀,让认证逻辑与next-intl的语言处理协同工作:
import createMiddleware from "next-intl/middleware"; import { localePrefix, locales } from "./navigation"; import { NextRequest, NextResponse } from "next/server"; export default function middleware(req: NextRequest) { const token = req.cookies.get("tbt")?.value; const isProtectedRoute = req.nextUrl.pathname.startsWith("/app"); // 提取当前请求的语言前缀并校验有效性 const currentLocale = req.nextUrl.pathname.split("/")[1]; const hasValidLocale = locales.includes(currentLocale); // 无token访问受保护路由:重定向到对应语言的登录页 if (!token && isProtectedRoute) { const loginPath = hasValidLocale ? `/${currentLocale}/login` : "/login"; const absoluteURL = new URL(loginPath, req.nextUrl.origin); return NextResponse.redirect(absoluteURL.toString()); } // 有token访问非受保护路由:重定向到对应语言的主页 if (token && !isProtectedRoute) { let explorePath = "/app/explore"; // 保留当前有效语言前缀 if (hasValidLocale) { explorePath = `/${currentLocale}/app/explore`; } // 处理从带语言的登录页跳转的情况 if (req.nextUrl.pathname.includes("/login")) { explorePath = hasValidLocale ? `/${currentLocale}/app/explore` : "/app/explore"; } const absoluteURL = new URL(explorePath, req.nextUrl.origin); return NextResponse.redirect(absoluteURL.toString()); } // 交由next-intl处理语言路由逻辑 return createMiddleware({ locales, localePrefix, defaultLocale: "en", })(req); } export const config = { matcher: ["/((?!api|_next|.*\\..*).*)"] };
关键修改点
- 提取并校验当前URL的语言前缀,确保重定向路径包含正确的语言标识
- 重定向时保留语言前缀,避免next-intl重复修改路径引发循环
- 针对登录页的跳转场景做特殊处理,保证目标路径与当前语言一致
内容的提问来源于stack exchange,提问作者Kuldeep
相关产品推荐
相关产品推荐

