🚪 当 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

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

相关推荐
Mintopia2 小时前
🚗💨 “八缸” 的咆哮:V8 引擎漫游记
前端·javascript·v8
源去_云走2 小时前
npm 包构建与发布
前端·npm·node.js
yunxi_052 小时前
让大模型会“说话”:基于 Spring WebSocket 的毫秒级流式 RAG 对话
java·后端
Sport2 小时前
面试官:聊聊 Webpack5 的优化方向
前端·面试
码农欧文2 小时前
关于npm和pnpm
前端·npm·node.js
Restart-AHTCM2 小时前
前端核心框架vue之(路由核心案例篇3/5)
前端·javascript·vue.js
二十雨辰2 小时前
vite快速上手
前端
Dxy12393102162 小时前
Python对图片进行加密,js前端进行解密
前端·javascript·python
支付宝体验科技2 小时前
SEE Conf 2025 来啦,一起探索 AI 时代的用户体验与工程实践!
前端