🚪 当 Next.js 中间件穿上保安制服:请求拦截与权限控制的底层奇幻之旅

1. 开场白:中间件是啥?能吃吗? 🤔

在 Next.js 的世界里,中间件(Middleware) 就像一家夜店的保安大叔。

它站在门口,拦截每一个 HTTP 请求,上下打量:

  • 你谁啊?(身份)
  • 你成年了吗?(权限)
  • 你包里不会藏着一把 rm -rf / 吧?(安全)

如果一切 OK,它潇洒地一挥手:NextResponse.next() ------ "进去嗨吧!"

如果不 OK,它直接一个 NextResponse.redirect('/sorry') ------ "门口右转,慢走不送。"


2. 底层小剧场:一次 HTTP 请求的一生 🎭

bash 复制代码
浏览器 ──GET /admin──> Next.js 边缘节点(Vercel Edge)─┐
                                                        │
                中间件大叔出马! 👮‍♂️                     │
                1. 解析 Cookie 🍪                        │
                2. 查数据库/缓存 🔍                      │
                3. 判断权限 🧠                          │
                4. 放人 or 扔人 🚪                      │
                                                        │
              ✅ 通过 ──> 真正的 /admin 页面             │
              ❌ 拒绝 ──> 302 /login                     │

小秘密:中间件默认运行在 Edge Runtime,即 V8 隔离沙箱 + 轻量级运行时,冷启动比你的咖啡还快 ☕️


3. 手撕代码:给保安大叔写一本《拦截秘籍》 📜

3.1 项目结构( Pages Router 也能用,但 App Router 更丝滑)

css 复制代码
src/
├─ middleware.js   ← 保安大叔的值班台
└─ app/
   ├─ admin/
   │  └─ page.js   ← VIP 包间
   └─ login/
      └─ page.js   ← 接待处

3.2 保安大叔上岗:middleware.js

js 复制代码
// 文件必须叫 middleware.js,Next.js 才会自动识别
import { NextResponse } from 'next/server'

// 需要拦截的路径前缀
const ADMIN_PREFIX = '/admin'

export function middleware(request) {
  const { pathname } = request.nextUrl
  const cookie = request.cookies.get('auth') // 掏出客户的小饼干 🍪

  // 如果不是 admin 路径,直接放人
  if (!pathname.startsWith(ADMIN_PREFIX)) {
    return NextResponse.next()
  }

  // 小饼干不存在?给张"好人卡"并踢到登录页
  if (!cookie || cookie.value !== 'super-secret-token') {
    const loginUrl = new URL('/login', request.url)
    loginUrl.searchParams.set('redirect', pathname) // 登录完还送你回来 ❤️
    return NextResponse.redirect(loginUrl)
  }

  // 小饼干合法,放行!
  return NextResponse.next()
}

// 告诉 Next.js 在哪条路口设卡
export const config = {
  matcher: ['/admin/:path*']
}

  1. Edge Runtime 限制

    没有 fs, 没有 child_process,连 Buffer 都是阉割版。

    所以别把 500MB 的用户头像塞 Cookie,保安大叔会哭。

  2. Cookie vs JWT vs Session

    • Cookie:轻,自带浏览器转发,适合"门禁卡"。
    • JWT:自包含,防篡改,但别把它当银行卡密码长度。
    • Session:重,需要中心存储,Edge 里玩不转。
      结论:边缘节点喜欢 Cookie + JWT 小套餐。
  3. 时间复杂度

    边缘函数冷启动 < 1ms,Crypto 验证签名 ≈ 0.2ms,数据库查询(Dynamo/Redis)≈ 3~5ms。

    总计仍比你读这句话的时间短。


5. 文学彩蛋:给代码加点浪漫主义 🌹

保安大叔也有春天。

夜里,他望着满天 console.log,轻声吟唱:

"你若 next(),便是晴天;你若 redirect(),我便 set-cookie 把你追回。"


6. 安全锦囊:别让保安大叔变成内鬼 🔐

坑位 诗意解释 代码级解药
1. 明文 Cookie "把钥匙写在门板上" httpOnly, secure, sameSite='lax'
2. XSS 偷饼干 "隔壁老王用吸管吸走小饼干" 前端 escapeHTML, CSP 头
3. CSRF 假刷卡 "坏人拿你的工牌刷闸机" 加 X-CSRF-Token 双重校验
4. 无限重定向 "鬼打墙" 登录后清 redirect 参数

7. 小结:把保安大叔打包带走 🎒

  1. 中间件 = Edge 保安,冷启动快得飞起。
  2. matcher 设卡,NextResponse 开门/踢人。
  3. Cookie/JWT 是门禁卡,别做成搬砖。
  4. 安全三板斧:httpOnly + secure + sameSite。
  5. 文学润色,让代码不再直男癌。

最后,祝每位开发者的请求都能被温柔以待,

愿每一位保安大叔都不会在深夜 console.error 里独自流泪。 🌙

保安大叔挥手.gif

"晚安,记得带小饼干来上班哦!"

相关推荐
UrbanJazzerati15 分钟前
AutoHotkey v2 零基础快速入门 Part 3 像素亮度检测完全指南
后端
浮链序16 分钟前
Shopify 把 10 亿商品开放给任意 agent 了:我用零依赖 Python 撸了个带预算闸门的代购网关
后端·代码规范
lovingsoft17 分钟前
Chrome Lighthouse 详解
前端·chrome
Qlly27 分钟前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝31 分钟前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦32 分钟前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
花涧鹤44 分钟前
学完循环我才发现,我写的不是死循环,是死机
后端
shmily麻瓜小菜鸡1 小时前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI1 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战