← 返回索引

认证 vs 授权:中间件分离设计

为什么 auth-middleware 和 permission-middleware 是分开的?

架构设计 中间件 RBAC 最佳实践

核心概念:两者职责不同

中间件 回答的问题 英文术语 文件位置
auth-middleware.js "你是谁?" Authentication(认证) backend/auth/
permission-middleware.js "你能做什么?" Authorization(授权) backend/middleware/

请求处理流程

请求进来
auth-middleware
解析 JWT → req.user
permission-middleware
检查 req.user 的权限
业务逻辑

为什么要分开?

1. 不是所有 API 都需要权限检查

// 只需要认证,不需要权限检查
router.get('/api/me/profile',
  authMiddleware,           // ✅ 只要登录就能看自己的资料
  getMyProfile
);

// 需要认证 + 权限
router.post('/api/appointments',
  authMiddleware,           // ✅ 先确认身份
  requirePermission('appointments:create'),  // ✅ 再检查权限
  createAppointment
);

// 公开 API,都不需要
router.get('/api/public/services',
  // 无中间件
  getPublicServices
);

2. 权限检查依赖认证结果

permission-middleware 需要知道用户是谁才能查权限表:

// auth-middleware 执行后,req.user 包含:
req.user = {
  id: 'user-123',
  role: 'manager',
  tenantId: 'tenant_qqnails',
  jobTitleId: 'jt-456'
};

// permission-middleware 用这些信息去查:
// 1. role_permissions 表(角色权限)
// 2. job_title_permissions 表(职位权限)
// 3. employee_special_permissions 表(特殊授权/拒绝)

3. 单一职责原则 (SRP)

auth-middleware 只关心

  • JWT 签名是否有效
  • Token 是否过期
  • Token 是否在黑名单中
  • 用户账户是否被锁定/禁用

permission-middleware 只关心

  • 用户角色有什么权限
  • 用户职位有什么权限
  • 是否有特殊 GRANT/DENY
  • 权限优先级计算

修改 JWT 验证逻辑不会影响权限逻辑,反之亦然。

4. 灵活组合

// 可选认证(有 token 就解析,没有也放行)
router.get('/api/products', optionalAuth, getProducts);

// 任一权限即可
router.get('/api/reports/summary',
  authMiddleware,
  requireAnyPermission(['reports:view', 'dashboard:view']),
  getReportSummary
);

// 必须同时拥有多个权限
router.delete('/api/employees/:id',
  authMiddleware,
  requireAllPermissions(['employees:delete', 'hr:manage']),
  deleteEmployee
);

如果合并会怎样?

问题

// 假设合并成一个中间件
function authAndPermission(permission) {
  return (req, res, next) => {
    // 1. JWT 验证逻辑
    // 2. 用户状态检查
    // 3. 权限查询逻辑
    // 4. 权限计算逻辑

    // ❌ 问题:不需要权限检查的 API 也被迫传参数
    // ❌ 问题:代码臃肿,难以测试
    // ❌ 问题:违反关注点分离原则
  }
}

// 用起来很别扭
router.get('/api/me/profile', authAndPermission(null), ...);  // 被迫传 null

业界标准

框架/语言 认证 授权 是否分离
Spring Security (Java) AuthenticationFilter AuthorizationFilter ✅ 分离
Django (Python) AuthenticationMiddleware @permission_required ✅ 分离
ASP.NET Core (C#) Authentication Authorization ✅ 分离
Express.js (Node) passport / jwt-middleware rbac / permission-middleware ✅ 分离

总结

这是经典的 Authentication vs Authorization 分离模式:

几乎所有成熟的后端框架都采用这种设计,因为它符合单一职责原则,提供更好的灵活性和可维护性。

更新于 2026-02-01 | Celoria 开发笔记