Next.js实现无Token跳转登录页时出现localhost多次重定向问题
无限重定向循环的原因及修复方案
核心原因
你陷入无限循环的关键问题出在当前页面的判断逻辑错误:
headersList.get("host")获取的是域名+端口(比如localhost:3000),永远不会等于localhost:3000/login——因为host字段仅包含域名和端口,不包含URL的路径部分。- 当用户被重定向到
/login页面时,RootLayout的鉴权逻辑依然会执行:此时Cookie里还是没有token,host依然是localhost:3000,完全满足!token && domain !== "localhost:3000/login"的判断条件,于是再次触发重定向,形成无限循环。
另外还有几个次要问题:
- 逻辑与运算符被错误转义成了
&&,实际应该是&&,否则逻辑判断会失效。 - 硬写完整域名
http://localhost:3000/login做重定向没必要,Next.js的redirect支持相对路径。 - 服务器组件里导入了客户端专用的
useRouter和Router,属于无效导入,应该移除。
修复后的代码
import type { Metadata } from "next"; import { Inter } from "next/font/google"; import "./globals.css"; import { AuthProvider } from "./_providers/AppProvider"; import AppLayout from "./AppLayout"; import { cookies } from "next/headers"; import { redirect } from "next/navigation"; import { headers } from "next/headers"; const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { title: "Loyalty", description: "Loyalty app", }; export default async function RootLayout({ children }: { children: React.ReactNode }) { const cookieStore = cookies(); const token = cookieStore.get("token")?.value; // 获取当前请求的路径(Next.js自动注入的请求头) const headersList = headers(); const pathname = headersList.get("x-nextjs-pathname") || ""; // 排除登录页,避免循环 if (!token && pathname !== "/login") { redirect("/login"); } return ( <html lang="en"> <body className={inter.className}> <AuthProvider> <AppLayout>{children}</AppLayout> </AuthProvider> </body> </html> ); }
关键修复点
- 用路径判断当前页面:通过
x-nextjs-pathname请求头获取当前页面的路径(Next.js自动注入),准确判断是否处于登录页,避免错误的host判断逻辑。 - 修正逻辑运算符:把
&&改成&&,确保逻辑判断的正确性。 - 使用相对路径重定向:直接用
redirect("/login"),无需硬写域名,适配不同环境。 - 移除无效导入:删掉客户端路由相关的
useRouter和Router导入,符合服务器组件的运行规则。
内容的提问来源于stack exchange,提问作者Lara
相关产品推荐
相关产品推荐

