Next.js 13 App Router中如何实现受保护/私有路由?
Next.js 13 App Router 路由权限实现方案
针对你的需求,下面给你几种实用的实现方式,适配Next.js 13 App Router的特性:
一、推荐:用中间件(Middleware)全局拦截
这种方式能统一保护所有/dashboard前缀的路由,是最安全高效的方案,因为中间件在请求到达页面之前就会执行。
- 在项目根目录创建
middleware.ts文件 - 编写校验逻辑:
import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { // 从Cookie中获取token(服务器端只能读取Cookie/请求头,无法读取localStorage) const authToken = request.cookies.get('auth_token')?.value; // 判断当前请求是否访问受保护的路由 const isAccessingProtectedRoute = request.nextUrl.pathname.startsWith('/dashboard'); // 无token且访问保护路由时,重定向到登录页 if (isAccessingProtectedRoute && !authToken) { return NextResponse.redirect(new URL('/login', request.url)); } // 校验通过,正常放行 return NextResponse.next(); } // 指定中间件生效的路由范围(只作用于dashboard下的所有子路由) export const config = { matcher: ['/dashboard/:path*'], };
二、服务器组件内做权限校验
如果只需要保护单个页面或layout,可以在dashboard的layout/page组件中直接校验:
// app/dashboard/layout.tsx import { redirect } from 'next/navigation'; import { cookies } from 'next/headers'; export default async function DashboardLayout({ children, }: { children: React.ReactNode; }) { // 从Cookie读取token const authToken = cookies().get('auth_token')?.value; // 无token则重定向到登录页 if (!authToken) { redirect('/login'); } return ( <div className="dashboard-container"> {children} </div> ); }
三、客户端组件的路由守卫(仅作补充)
如果你的页面是客户端组件(带'use client'指令),可以用客户端逻辑校验,但这种方式有漏洞(用户可通过禁用JS绕过),仅作补充场景使用:
'use client'; import { useEffect } from 'react'; import { useRouter } from 'next/navigation'; export default function DashboardClientPage() { const router = useRouter(); useEffect(() => { // 从localStorage读取token(仅客户端可用) const authToken = localStorage.getItem('auth_token'); if (!authToken) { router.push('/login'); } }, [router]); return ( <div>我的仪表盘</div> ); }
注意事项
- 存储token推荐用HttpOnly+Secure的Cookie,这种方式更安全,且服务器端、中间件都能读取,避免客户端存储的安全风险。
- 你的
(auth)路由组如果是登录相关页面,建议放在根目录下(比如app/(auth)/login/page.tsx),不要放在dashboard目录下,否则会被权限拦截。
内容的提问来源于stack exchange,提问作者Sohaib Ashraf
相关产品推荐
相关产品推荐

