当前位置: 首页 > news >正文

Next.js中Protected Route(受保护路由)

文章目录

  • 前言
  • ✅ Next.js 中实现受保护路由的方式(按场景拆解)
    • ✅ 1. `app/` 目录(React Server Components + 中间件支持)
      • 🧠 原理一:使用 `Middleware` 拦截请求
        • 示例:`middleware.ts`
        • 配置 `matcher`(可选)
    • ✅ 2. `app/` 目录中的 Server Component 页面中校验
    • ✅ 3. `pages/` 目录传统方式:HOC 保护组件
    • ✅ 4. 使用 Layout 组件统一包裹所有受保护页面
    • ✅ 常用令牌/登录状态判断方法
    • ✅ 总结:Next.js 实现 Protected Route 的几种机制
    • 🧱 文件结构建议:
    • ✅ 1. `lib/auth.ts` 示例(伪代码)
    • ✅ 2. `app/(protected)/layout.tsx` 实现核心保护逻辑
    • ✅ 3. `app/(protected)/dashboard/page.tsx` 示例受保护页面
    • ✅ 4. `app/(auth)/login/page.tsx` 示例登录页
    • ✅ ✅ 总结:受保护路由实现流程


前言

Next.js 中,Protected Route(受保护路由) 的核心目的是:

🛡️ 限制未登录用户访问某些页面,并在需要时重定向到登录页。


✅ Next.js 中实现受保护路由的方式(按场景拆解)


✅ 1. app/ 目录(React Server Components + 中间件支持)

适用于 Next.js 13+/14+ 新架构

🧠 原理一:使用 Middleware 拦截请求

在请求进入页面前,判断用户是否有权限,若无则跳转。

示例:middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'export function middleware(request: NextRequest) {const token = request.cookies.get('token')?.valueconst protectedPaths = ['/dashboard', '/profile']const isProtected = protectedPaths.some(path =>request.nextUrl.pathname.startsWith(path))if (isProtected && !token) {const loginUrl = new URL('/login', request.url)return NextResponse.redirect(loginUrl)}return NextResponse.next()
}
配置 matcher(可选)
export const config = {matcher: ['/dashboard/:path*', '/profile/:path*']
}

✅ 2. app/ 目录中的 Server Component 页面中校验

适用于 app/dashboard/page.tsx 这种服务端渲染页面

import { redirect } from 'next/navigation'
import { getUserFromCookie } from '@/lib/auth'export default async function DashboardPage() {const user = await getUserFromCookie()if (!user) redirect('/login') // 服务器重定向,跳过渲染return <div>Hello, {user.name}</div>
}

✅ 3. pages/ 目录传统方式:HOC 保护组件

适用于 Next.js pages/ 路由老架构。

function withAuth(Component) {return function AuthWrapper(props) {const isLoggedIn = typeof window !== 'undefined' && localStorage.getItem('token')if (!isLoggedIn) {if (typeof window !== 'undefined') {window.location.href = '/login'}return null}return <Component {...props} />}
}

然后:

export default withAuth(MyPage)

⚠️ 缺点:客户端重定向,可能会闪烁。


✅ 4. 使用 Layout 组件统一包裹所有受保护页面

app/ 中创建:

// app/(auth)/layout.tsx → 公共 Layout(登录页)
export default function AuthLayout({ children }) {return <>{children}</>
}// app/(protected)/layout.tsx → 需要登录的 Layout
import { redirect } from 'next/navigation'
import { getUserFromCookie } from '@/lib/auth'export default async function ProtectedLayout({ children }) {const user = await getUserFromCookie()if (!user) redirect('/login')return <>{children}</>
}

然后受保护页面放在 /app/(protected)/dashboard/page.tsx


✅ 常用令牌/登录状态判断方法

场景判断依据
服务端请求cookies().get('token')
客户端导航localStorage.getItem('token')
NextAuth.jsuseSession() / getServerSession()
Auth0/Supabaseuser?.id / auth.user() 等 SDK 状态

✅ 总结:Next.js 实现 Protected Route 的几种机制

方法场景优点缺点
middleware.ts所有页面预拦截全局无闪烁逻辑较简单(仅可读 cookie)
✅ Server Redirect(redirect()app/ 目录渲染前跳转,安全SSR-only,不适合纯客户端页面
⚠️ 客户端 HOCpages/适合老架构会闪烁,前端可见
✅ layout.tsx 内部控制app/ 分组控制灵活、分层控制依赖 SSR,适配复杂逻辑

Next.js app/ 目录结构(RSC 架构) 的完整【受保护路由方案模板】
涵盖:

  • ✅ 使用 Layout 封装受保护区域(如 /dashboard
  • ✅ 服务端安全校验(使用 cookies() 获取 token)
  • ✅ 自动跳转到 /login
  • ✅ 可扩展集成真实认证逻辑(如 JWT、Session、Supabase、NextAuth 等)

🧱 文件结构建议:

app/
├─ (auth)/            ← 登录、注册等不需要登录的页面
│   └─ login/page.tsx
├─ (protected)/       ← 所有需要登录的受保护页面
│   ├─ layout.tsx     ← 在这里实现登录校验逻辑
│   └─ dashboard/page.tsx
lib/
└─ auth.ts            ← 封装 token 解析 / 获取当前用户

✅ 1. lib/auth.ts 示例(伪代码)

你可以接入实际的鉴权逻辑(如 JWT 解密、查数据库、调用 API):

import { cookies } from 'next/headers'export async function getCurrentUser() {const cookieStore = cookies()const token = cookieStore.get('token')?.valueif (!token) return null// 示例:从 token 解密用户信息try {const user = JSON.parse(atob(token.split('.')[1]))return user} catch (e) {return null}
}

✅ 2. app/(protected)/layout.tsx 实现核心保护逻辑

// app/(protected)/layout.tsx
import { redirect } from 'next/navigation'
import { getCurrentUser } from '@/lib/auth'export default async function ProtectedLayout({children,
}: {children: React.ReactNode
}) {const user = await getCurrentUser()if (!user) {redirect('/login') // ⛔ 未登录,跳转登录页}return <>{children}</>
}

✅ 3. app/(protected)/dashboard/page.tsx 示例受保护页面

export default function DashboardPage() {return (<div className="p-4"><h1 className="text-xl font-bold">欢迎进入控制台</h1></div>)
}

所有在 (protected)/ 分组下的页面都会自动被该 layout.tsx 包裹并执行鉴权。


✅ 4. app/(auth)/login/page.tsx 示例登录页

你可以在此页设置登录状态并存入 cookie(建议使用 Set-Cookie 响应头或服务端设置):

'use client'
import { useRouter } from 'next/navigation'export default function LoginPage() {const router = useRouter()const handleLogin = async () => {// 假设后台返回 tokendocument.cookie = `token=your_token; path=/`router.push('/dashboard')}return (<div><h1>登录</h1><button onClick={handleLogin}>一键登录</button></div>)
}

✅ ✅ 总结:受保护路由实现流程

User Browser ProtectedLayout getCurrentUser DB/Token解析 访问 /dashboard 渲染前请求 layout.tsx 读取 cookies/token 解析用户 渲染子页面 redirect('/login') alt [有效用户] [未登录或非法] User Browser ProtectedLayout getCurrentUser DB/Token解析

相关文章:

  • reverse笔记
  • Neo4j 完全指南:从入门到精通
  • 八:操作系统设备管理之缓冲、缓存与假脱机
  • 编程技能:格式化打印05,格式控制符
  • NVM!(可以快速替换你的node版本)
  • 免费wordpress模板下载
  • 神经网络与深度学习 网络优化与正则化
  • 63、.NET 异常处理
  • [QMT量化交易小白入门]-六十一、多因子选股+布林带择时年化收益率21.5%
  • FPGA 的硬件结构
  • 成工fpga(知识星球号)——精品来袭
  • PySpark性能调优手册:大数据处理中的避坑与实践
  • GC1809:高性能24bit/192kHz音频接收芯片解析
  • 《一生一芯》数字实验六:实现随机数发生器
  • Dockerfile实践java项目
  • Postgresql常用函数操作
  • uniapp中使用aixos 报错
  • 「数据分析 - NumPy 函数与方法全集」【数据分析全栈攻略:爬虫+处理+可视化+报告】
  • 国际数字影像产业园:为文创产业注入科技基因,激活无限可能
  • 益莱储参加 Keysight World 2025,助力科技加速创新
  • 茶文化网站制作/网上找客户有什么渠道
  • 上海十大网站建设/推广品牌的策划方案
  • 网站建设详细教程视频/企业管理培训课程视频
  • 网站建设万网/成都最新疫情
  • 中国糕点网页设计网站/售卖链接
  • 网站销售怎么做的/北京计算机培训机构哪个最好