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*']
}
4. 底层知识加餐:为什么 Cookie 是"小饼干"而不是"小面包"? 🍪
-
Edge Runtime 限制
没有
fs
, 没有child_process
,连Buffer
都是阉割版。所以别把 500MB 的用户头像塞 Cookie,保安大叔会哭。
-
Cookie vs JWT vs Session
- Cookie:轻,自带浏览器转发,适合"门禁卡"。
- JWT:自包含,防篡改,但别把它当银行卡密码长度。
- Session:重,需要中心存储,Edge 里玩不转。
结论:边缘节点喜欢 Cookie + JWT 小套餐。
-
时间复杂度
边缘函数冷启动 < 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. 小结:把保安大叔打包带走 🎒
- 中间件 = Edge 保安,冷启动快得飞起。
matcher
设卡,NextResponse
开门/踢人。- Cookie/JWT 是门禁卡,别做成搬砖。
- 安全三板斧:
httpOnly
+secure
+sameSite
。 - 文学润色,让代码不再直男癌。
最后,祝每位开发者的请求都能被温柔以待,
愿每一位保安大叔都不会在深夜
console.error
里独自流泪。 🌙
保安大叔挥手.gif
"晚安,记得带小饼干来上班哦!"