Next.js Middleware 与鉴权:生活应用的安全层不能只靠客户端判断 Next.js Middleware 与鉴权生活应用的安全层不能只靠客户端判断一、生活数据的鉴权比业务应用更敏感但资源更少生活应用的数据鉴权有独特矛盾。数据本身比业务应用更敏感——日记、情绪记录、消费详情都是高度私密信息。但生活应用的开发资源和运维投入远少于企业级产品。很多独立开发的生活应用甚至没有专门的运维人员。鉴权如果只靠客户端判断风险很高。客户端的 localStorage 或 session 可以被篡改请求参数可以被修改。一个生活应用如果只在前端检查用户身份任何人都可以伪造请求获取其他用户的日记内容。这不是理论风险而是生活应用常见的实际漏洞。Next.js Middleware 提供了服务端鉴权的入口点。它在请求到达页面之前执行可以验证身份、检查权限、拦截未授权访问。生活应用应该把鉴权放在 Middleware 层而不是只依赖客户端的 UI 判断。二、Middleware 鉴权的层级设计鉴权应该分层执行。Middleware 做身份验证和粗粒度权限检查页面层做细粒度数据权限控制。flowchart TD A[用户请求] -- B[Middleware身份验证] B -- C{有效身份} C --|否| D[重定向到登录页] C --|是| E[Middleware路由权限检查] E -- F{允许访问此路由} F --|否| G[返回403] F --|是| H[页面层数据权限控制] H -- I[只返回该用户自己的数据] I -- J[页面渲染]两层鉴权的分工明确。Middleware 确保这个人是谁和他能不能看这个页面页面层确保他只能看到自己的数据。粗粒度用 Middleware 快速拦截细粒度在页面层精确过滤。三、Next.js Middleware 鉴权实现// middleware.ts // Next.js Middleware生活应用的身份验证和路由权限检查 import { NextRequest, NextResponse } from next/server; // 需要鉴权的路由列表 const protectedRoutes [/diary, /emotion, /expense, /settings]; // 公开路由不需要鉴权 const publicRoutes [/login, /register, /about]; export function middleware(request: NextRequest) { const { pathname } request.nextUrl; // 公开路由直接放行 if (publicRoutes.some((r) pathname.startsWith(r))) { return NextResponse.next(); } // 检查鉴权token const token request.cookies.get(auth_token)?.value; if (!token) { // 未登录用户重定向到登录页保留原始URL便于登录后跳回 const loginUrl new URL(/login, request.url); loginUrl.searchParams.set(redirect, pathname); return NextResponse.redirect(loginUrl); } // 验证token有效性简单签名检查不调用外部服务 if (!verifyTokenSignature(token)) { // token无效时清除cookie并重定向到登录 const response NextResponse.redirect(new URL(/login, request.url)); response.cookies.delete(auth_token); return response; } return NextResponse.next(); } // 简单token签名验证防止客户端伪造 function verifyTokenSignature(token: string): boolean { try { // token格式base64(userId).base64(signature) const parts token.split(.); if (parts.length ! 2) return false; const [payload, signature] parts; // 使用环境变量中的密钥验证签名 const expectedSig signPayload(payload, process.env.AUTH_SECRET ?? ); return signature expectedSig; } catch { return false; } } export const config { matcher: [/((?!api|_next/static|_next/image|favicon.ico).*)], };Middleware 不应该做外部服务调用比如调用数据库验证用户详情。Middleware 的执行频率高每次请求都会经过外部调用会增加延迟和失败风险。身份验证用 token 签名检查数据权限在页面层做数据库查询。四、Middleware 的性能和部署边界Middleware 在 Vercel 上的执行有冷启动问题。首次请求时 Middleware 需要初始化可能增加几百毫秒延迟。生活应用的流量通常不大冷启动影响有限。但如果流量波动大比如推送后突然涌入用户冷启动会集中发生。Middleware 的另一个限制是不能访问 Node.js 的完整 API。它运行在 Edge Runtime 上不支持 fs、crypto 等模块。上面的签名验证用了简单字符串比较而非 crypto 模块就是为了适配 Edge Runtime。生产环境应该用 jose 等 Edge 兼容的 JWT 库做更安全的验证。生活应用还需要考虑多设备登录的场景。用户可能在手机和电脑上同时使用。token 签发时应该包含设备信息不同设备的 token 管理应该独立。单设备踢出不应该影响其他设备的登录状态。五、总结生活应用鉴权应在 Next.js Middleware 层做身份验证和路由权限检查页面层做数据权限过滤。Middleware 不做外部服务调用只用 token 签名验证确保快速响应。公开路由直接放行受保护路由未登录时重定向到登录页。Edge Runtime 限制下用兼容库替代 Node.js API。多设备登录需要独立 token 管理。