# 权限系统设计文档 (Crawlful Hub)

> **定位**：Crawlful Hub 权限系统设计文档 - 定义基于角色的访问控制（RBAC）和数据级权限。
> **更新日期**: 2026-03-18
> **最高优先级参考**: [Service_Design.md](./Service_Design.md)

---

## 1. 权限系统概述

### 1.1 核心概念

- **角色（Role）**：一组权限的集合
- **权限（Permission）**：对资源的操作许可
- **用户（User）**：系统的使用者
- **资源（Resource）**：系统中的对象，如商品、订单、用户等
- **数据级权限**：基于数据属性的访问控制

### 1.2 重要性

良好的权限系统可以：
- 保护系统安全
- 确保数据隐私
- 实现职责分离
- 满足合规要求
- 提供可审计性

---

## 2. RBAC 模型

### 2.1 角色定义

| 角色 | 描述 | 权限范围 |
|------|------|----------|
| **ADMIN** | 系统管理员 | 所有资源的所有操作 |
| **MANAGER** | 运营主管 | 大部分资源的管理操作 |
| **OPERATOR** | 运营专员 | 基础运营操作 |
| **FINANCE** | 财务主管 | 财务相关操作 |
| **SOURCING** | 采购专家 | 采购相关操作 |
| **LOGISTICS** | 物流专家 | 物流相关操作 |
| **ANALYST** | 数据分析师 | 数据分析相关操作 |

### 2.2 权限定义

| 权限 | 描述 | 适用资源 |
|------|------|----------|
| **CREATE** | 创建资源 | 所有资源 |
| **READ** | 读取资源 | 所有资源 |
| **UPDATE** | 更新资源 | 所有资源 |
| **DELETE** | 删除资源 | 所有资源 |
| **APPROVE** | 审批操作 | 订单、结算等 |
| **EXPORT** | 导出数据 | 报表、数据等 |
| **IMPORT** | 导入数据 | 商品、用户等 |

### 2.3 权限分配

**示例**：
```typescript
// 角色权限映射
const rolePermissions = {
  ADMIN: ['*'], // 所有权限
  MANAGER: [
    'CREATE:product', 'READ:product', 'UPDATE:product', 'DELETE:product',
    'CREATE:order', 'READ:order', 'UPDATE:order', 'APPROVE:order',
    'READ:report', 'EXPORT:report'
  ],
  OPERATOR: [
    'READ:product', 'UPDATE:product',
    'READ:order', 'UPDATE:order'
  ],
  FINANCE: [
    'READ:order', 'READ:settlement', 'APPROVE:settlement',
    'READ:report', 'EXPORT:report'
  ],
  SOURCING: [
    'CREATE:product', 'READ:product', 'UPDATE:product',
    'READ:supplier', 'CREATE:supplier', 'UPDATE:supplier'
  ],
  LOGISTICS: [
    'READ:order', 'UPDATE:order',
    'READ:inventory', 'UPDATE:inventory'
  ],
  ANALYST: [
    'READ:report', 'EXPORT:report'
  ]
};
```

---

## 3. 数据级权限

### 3.1 定义

数据级权限是指基于数据属性的访问控制，确保用户只能访问和操作与自己相关的数据。

### 3.2 实现方法

#### 3.2.1 租户隔离

**定义**：不同租户的数据相互隔离

**实现**：
- 在所有数据表中添加 `tenantId` 字段
- 在所有查询中默认带上 `tenantId` 过滤
- 确保跨租户操作的安全性

**示例**：
```typescript
// 数据访问层
class ProductRepository {
  async findAll(tenantId: string, params?: any): Promise<Product[]> {
    return await Product.findAll({
      where: {
        tenantId,
        ...params
      }
    });
  }
  
  async findById(id: string, tenantId: string): Promise<Product | null> {
    return await Product.findOne({
      where: {
        id,
        tenantId
      }
    });
  }
}
```

#### 3.2.2 店铺隔离

**定义**：同一租户下不同店铺的数据相互隔离

**实现**：
- 在相关数据表中添加 `shopId` 字段
- 在查询中根据用户的店铺权限过滤
- 确保用户只能访问自己有权限的店铺数据

**示例**：
```typescript
// 权限服务
class RBACService {
  async checkShopAccess(userId: string, shopId: string): Promise<boolean> {
    const user = await this.userRepository.findById(userId);
    const userShops = await this.userShopRepository.findByUserId(userId);
    return userShops.some(us => us.shopId === shopId) || user.role === 'ADMIN';
  }
}

// 订单服务
class OrderService {
  async getOrders(userId: string, params?: any): Promise<Order[]> {
    const user = await this.userRepository.findById(userId);
    
    if (user.role === 'ADMIN') {
      return await this.orderRepository.findAll(params);
    }
    
    const userShops = await this.userShopRepository.findByUserId(userId);
    const shopIds = userShops.map(us => us.shopId);
    
    return await this.orderRepository.findAll({
      ...params,
      shopId: shopIds
    });
  }
}
```

#### 3.2.3 字段级权限

**定义**：基于字段的访问控制

**实现**：
- 定义字段级权限规则
- 在返回数据时过滤敏感字段
- 确保用户只能看到和修改自己有权限的字段

**示例**：
```typescript
// 字段级权限
const fieldPermissions = {
  ADMIN: {
    product: ['*'], // 所有字段
    user: ['*']
  },
  MANAGER: {
    product: ['id', 'name', 'price', 'stock'],
    user: ['id', 'name', 'email']
  },
  OPERATOR: {
    product: ['id', 'name', 'price'],
    user: ['id', 'name']
  }
};

// 数据过滤
function filterFields(data: any, fields: string[]): any {
  if (fields.includes('*')) {
    return data;
  }
  
  const filtered: any = {};
  fields.forEach(field => {
    if (data[field] !== undefined) {
      filtered[field] = data[field];
    }
  });
  
  return filtered;
}
```

### 3.3 最佳实践

- **默认带租户ID**：所有查询默认带 `tenantId` 过滤
- **权限检查前置**：在业务逻辑开始前检查权限
- **统一权限服务**：使用统一的权限服务处理权限检查
- **缓存权限**：缓存用户权限，提高性能
- **审计日志**：记录权限相关操作的审计日志

---

## 4. 权限验证

### 4.1 实现方法

#### 4.1.1 中间件验证

**适用场景**：API 路由权限验证

**实现**：
- 创建权限验证中间件
- 在路由中应用中间件
- 验证用户是否有权限访问资源

**示例**：
```typescript
// 权限中间件
const authorize = (requiredPermission: string) => {
  return (req, res, next) => {
    const user = req.user;
    
    if (!user) {
      return res.status(401).json({ error: 'Unauthorized' });
    }
    
    if (!user.permissions.includes(requiredPermission) && user.role !== 'ADMIN') {
      return res.status(403).json({ error: 'Forbidden' });
    }
    
    next();
  };
};

// 使用
app.get('/products', authorize('READ:product'), productController.getProducts);
app.post('/products', authorize('CREATE:product'), productController.createProduct);
```

#### 4.1.2 服务层验证

**适用场景**：业务逻辑权限验证

**实现**：
- 在服务层检查权限
- 验证用户是否有权限操作资源
- 验证用户是否有权限访问数据

**示例**：
```typescript
async updateProduct(productId: string, updates: Partial<Product>, userId: string): Promise<Product> {
  // 检查操作权限
  if (!this.rbacService.hasPermission(userId, 'UPDATE:product')) {
    throw new ForbiddenException('You do not have permission to update products');
  }
  
  // 获取商品
  const product = await this.productRepository.findById(productId);
  if (!product) {
    throw new NotFoundException('Product not found');
  }
  
  // 检查数据权限
  if (!this.rbacService.hasDataAccess(userId, product.tenantId, product.shopId)) {
    throw new ForbiddenException('You do not have access to this product');
  }
  
  // 更新商品
  Object.assign(product, updates);
  return await this.productRepository.save(product);
}
```

### 4.2 最佳实践

- **多层验证**：在中间件和服务层都进行权限验证
- **明确的错误信息**：返回清晰的权限错误信息
- **权限缓存**：缓存用户权限，提高验证性能
- **定期权限检查**：定期检查权限配置的正确性

---

## 5. 权限管理

### 5.1 角色管理

- **创建角色**：定义新角色
- **修改角色**：修改角色的权限
- **删除角色**：删除不需要的角色
- **分配角色**：为用户分配角色

### 5.2 权限管理

- **定义权限**：定义新的权限
- **分配权限**：为角色分配权限
- **回收权限**：从角色中回收权限

### 5.3 用户管理

- **创建用户**：创建新用户并分配角色
- **修改用户**：修改用户的角色和权限
- **删除用户**：删除用户
- **禁用用户**：暂时禁用用户

---

## 6. 安全考虑

### 6.1 防止权限提升

- **最小权限原则**：用户只获得必要的权限
- **权限审计**：定期审计权限配置
- **权限边界**：明确权限的边界

### 6.2 防止数据泄露

- **数据加密**：加密敏感数据
- **访问控制**：严格控制数据访问
- **审计日志**：记录数据访问日志

### 6.3 防止暴力破解

- **密码策略**：强密码要求
- **登录限制**：限制登录尝试次数
- **验证码**：使用验证码防止暴力破解

---

## 7. 测试策略

### 7.1 单元测试

- 测试权限验证逻辑
- 测试角色权限映射
- 测试数据级权限过滤

### 7.2 集成测试

- 测试完整的权限流程
- 测试不同角色的访问控制
- 测试数据级权限的有效性

### 7.3 安全测试

- 测试权限提升攻击
- 测试数据泄露风险
- 测试暴力破解防护

---

## 8. 相关文档

- [Service_Design.md](./Service_Design.md)
- [Data_Consistency.md](./Data_Consistency.md)
- [API_Specs](./API_Specs/)

---

*本文档基于服务设计文档，最后更新: 2026-03-18*