Vibe Tutorial
环境变量与安全机制

6.6 Middleware 路由保护

Tip

学会用Middleware保护敏感路由,实现服务端验证,避免未授权访问。


1. 为什么要学这个?

你做了一个博客系统,有一个后台管理页面/admin。你在首页写了代码:if (!user.isAdmin) return null;来隐藏入口按钮。你觉得很安全。

直到有一天,一个竞争对手直接在地址栏输入了https://your-blog.com/admin。页面直接跳了出来,他不仅能看,还能删你的文章。

前端隐藏只是掩耳盗铃——任何人都能直接访问URL,删光你的数据。


2. 核心概念

2.1 Middleware - 中间件保护机制

技术定义:Next.js Middleware是全栈框架中的拦截层,运行在每一个HTTP请求到达渲染引擎或静态资源获取之前。它在边缘运行时(Edge Runtime)执行,允许开发者通过检查Cookies、Headers或Auth Token来实现全局的身份认证、路径重定向及地理位置过滤。

sequenceDiagram
    participant User as "用户(Client)"
    participant Middleware as "保安(Middleware)"
    participant Page as "机密页面(/admin)"
    participant Login as "登录页(/login)"
    
    User->>Middleware: 1. 偷袭可以直接访问/admin吗?
    Note over Middleware: 检查是否携带Session Token
    alt 没带证件
        Middleware-->>User: 2. 滚!重定向到/login
    else 带了证件
        Middleware->>Page: 2. 放行
        Page-->>User: 3. 返回页面内容
    end

3. 代码实战

在项目根目录(app同级)创建middleware.ts:

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

// 1. 指定拦截哪些路径(Matcher)
export const config = {
  matcher: ['/admin/:path*', '/dashboard/:path*'],
}

export function middleware(request: NextRequest) {
  // 2. 检查是否有Token(Cookie)
  const token = request.cookies.get('session_token')
  
  // 3. 如果没Token,踢回登录页
  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url))
  }
  
  // 4. 甚至可以调API验证Token有效性...
  
  // 5. 放行
  return NextResponse.next()
}

4. 应用场景

🎯 场景 动作
后台保护 访问/dashboard/admin时,检查是否登录
国际化(i18n) 访问/about时,自动根据浏览器语言跳到/zh/about/en/about
A/B测试 随机把50%用户重定向到新版页面

5. 避坑指南

✅ 推荐做法 ❌ 禁忌
使用Matcher过滤路径 拦截全局所有请求(导致静态图片加载变慢)
只做轻量级校验 在中间件里查数据库(中间件运行在边缘节点,可能连不上数据库且超时)
配合前端重定向 只靠前端useEffect跳转(会有闪屏,且不安全)

6. 真实案例

Story

2019年,第一美国金融公司8.85亿份文件泄露

First American Financial Corp是美国最大的产权保险公司之一。漏洞原理:IDOR(不安全的直接对象引用)。他们的网站允许通过URL查看文件,类似website.com/document?id=100。竟然没有任何中间件验证来检查"当前用户是否有权查看文件#100"。只要你把URL里的数字改成101,就能看到别人的房产证、银行账号和社保号。后果:8.85亿份敏感文件裸露,公司股价暴跌,面临SEC严厉指控。

Vibe心法:不要指望用户会乖乖点击链接——敏感地址必须在Middleware层安排保安,无验证不放行。


7. 本章小结

  1. 🛡️ 保安机制:Middleware是请求到达页面之前的最后一道防线
  2. 🔐 服务端验证:不要依赖前端useRouter跳转,那只是为了体验,不是为了安全
  3. 🚫 最小权限:默认拦截所有敏感路由,只有验证通过才放行