168 lines
7.5 KiB
Markdown
168 lines
7.5 KiB
Markdown
|
|
# 软件使用授权控制方案(BodyBalanceEvaluation)
|
|||
|
|
|
|||
|
|
本文档针对 BodyBalanceEvaluation 的当前技术架构(Electron + 前端、Python Flask 后端、Windows 打包)设计一套合理、可落地的软件使用授权控制方案。方案兼顾离线可用、安全可靠、易于运维与用户体验。
|
|||
|
|
|
|||
|
|
## 目标与原则
|
|||
|
|
|
|||
|
|
- 合法控制软件使用范围与授权期限,满足试用、商用等场景。
|
|||
|
|
- 支持离线运行(无网络环境),可选在线激活与续期。
|
|||
|
|
- 与当前项目架构低耦合,易于集成与维护。
|
|||
|
|
- 安全合规:私钥不落地、授权文件不可伪造、关键流程可审计。
|
|||
|
|
|
|||
|
|
## 授权类型
|
|||
|
|
|
|||
|
|
- 试用授权(Trial):
|
|||
|
|
- 有效期短(如 7/14/30 天),功能有限制(如录制时长、导出功能、带水印)。
|
|||
|
|
- 标准授权(Per-Device):
|
|||
|
|
- 绑定单机硬件指纹,在有效期内完整功能可用。
|
|||
|
|
|
|||
|
|
|
|||
|
|
## 授权架构设计
|
|||
|
|
|
|||
|
|
- 离线优先 + 在线可选:
|
|||
|
|
- 核心授权依赖本地授权文件(License File)。
|
|||
|
|
- 在线激活与续期通过授权服务器获取签名授权文件。
|
|||
|
|
- 授权文件(License)格式:JSON + 数字签名(RSA/ECC):
|
|||
|
|
- 字段示例:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"product": "BodyBalanceEvaluation",
|
|||
|
|
"version": "1.0.0",
|
|||
|
|
"license_id": "LIC-2025-0001",
|
|||
|
|
"license_type": "per_device",
|
|||
|
|
"machine_id": "W10-ABCDEF123456",
|
|||
|
|
"issued_at": "2025-10-01T00:00:00Z",
|
|||
|
|
"expires_at": "2026-10-01T00:00:00Z",
|
|||
|
|
"features": { "recording": true, "export": true, "trial_limit_minutes": null },
|
|||
|
|
"signature": "<RSA-SHA256-BASE64>"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
- 私钥仅存放在授权服务器,后端内嵌公钥用于验证签名。
|
|||
|
|
- 授权关联:
|
|||
|
|
- `machine_id` 使用硬件指纹(CPU/主板/磁盘序列/MAC 等)生成并哈希化。
|
|||
|
|
- 授权文件通过签名绑定 `machine_id`,离线不可移植至不同机器。
|
|||
|
|
|
|||
|
|
## 集成点与流程
|
|||
|
|
|
|||
|
|
### 后端集成(Python Flask)
|
|||
|
|
|
|||
|
|
- 配置路径:统一通过设备侧 `ConfigManager` 读取授权文件路径与公钥路径。
|
|||
|
|
- `backend/devices/utils/config_manager.py`
|
|||
|
|
- `config.ini` 示例:
|
|||
|
|
```ini
|
|||
|
|
[LICENSE]
|
|||
|
|
path = data/license.json
|
|||
|
|
public_key = backend/license_pub.pem
|
|||
|
|
grace_days = 3
|
|||
|
|
```
|
|||
|
|
- 初始化检查:在 `backend/main.py` 的 `AppServer.init_app()` 中执行:
|
|||
|
|
- 生成或读取 `machine_id`(硬件指纹)。
|
|||
|
|
- 加载授权文件,校验签名与有效期、匹配 `machine_id`。
|
|||
|
|
- 记录授权状态(有效、过期、试用、无授权)到日志与数据库(可选)。
|
|||
|
|
- API 访问控制:
|
|||
|
|
- 对关键路由施加授权检查(装饰器/中间件),如:
|
|||
|
|
- `POST /api/detection/start`、`/stop`、数据导出、录制等。
|
|||
|
|
- 授权失败返回明确的错误码与提示(含续期/激活建议)。
|
|||
|
|
- 试用/降级策略:
|
|||
|
|
- 提供最小可用功能(如实时预览)但限制录制时长或导出。
|
|||
|
|
- 局部特性禁用或添加水印(在屏幕录制或图像导出路径中处理)。
|
|||
|
|
- 容错与灰度:
|
|||
|
|
- 支持 `grace_days` 宽限期(网络异常或时间漂移时可用)。
|
|||
|
|
- 缓存最近一次有效授权状态,定时复核(避免频繁磁盘访问)。
|
|||
|
|
|
|||
|
|
### 前端集成(Electron + 前端页面)
|
|||
|
|
|
|||
|
|
- 激活流程:
|
|||
|
|
- 提供激活页:显示 `machine_id` 与授权状态。
|
|||
|
|
- 在线激活:提交序列号/订单号至授权服务器,服务端返回签名授权文件;前端保存至 `[LICENSE].path`。
|
|||
|
|
- 离线激活:导出激活请求文件(含 `machine_id` 与产品信息),由管理员获取授权文件后导入。
|
|||
|
|
- 交互与提示:
|
|||
|
|
- 主界面顶部/设置页显示授权状态与到期时间。
|
|||
|
|
- 到期前 7/15 天提醒,试用版显示限制说明。
|
|||
|
|
- 授权失效时提供指引按钮(联系支持/打开激活页)。
|
|||
|
|
|
|||
|
|
## 安全策略与对抗
|
|||
|
|
|
|||
|
|
- 授权文件签名验证:后端使用公钥验证 `signature`,拒绝未签名或签名不匹配的授权。
|
|||
|
|
- 硬件指纹防篡改:
|
|||
|
|
- 组合多项硬件指标,fallback 与去重策略避免单项变化导致不可用。
|
|||
|
|
- 指纹哈希,不原样存储,保护隐私。
|
|||
|
|
- 反调试与完整性检测(可选):
|
|||
|
|
- 检测调试器或关键文件篡改(哈希校验),异常时降级或停止。
|
|||
|
|
- 日志与审计:
|
|||
|
|
- 授权校验、激活、失效事件写入日志与数据库,便于问题定位。
|
|||
|
|
|
|||
|
|
## 关键实现要点(建议代码位置)
|
|||
|
|
|
|||
|
|
- 授权模块:`backend/devices/utils/license_manager.py`(新增)
|
|||
|
|
- 方法示例:
|
|||
|
|
- `get_machine_id()`: 采集硬件信息并生成指纹。
|
|||
|
|
- `load_license(path)`: 读取并解析授权文件。
|
|||
|
|
- `verify_signature(license, public_key_path)`: 验证数字签名。
|
|||
|
|
- `check_validity(license, machine_id, now, grace_days)`: 有效期与绑定校验。
|
|||
|
|
- 后端入口:`backend/main.py`
|
|||
|
|
- 在 `AppServer.init_app()` 中:
|
|||
|
|
- 加载 `ConfigManager` → 初始化授权模块 → 设置 `self.license_status`。
|
|||
|
|
- 根据 `self.license_status` 控制设备初始化与 API 开放范围。
|
|||
|
|
- 装饰器示例:
|
|||
|
|
```python
|
|||
|
|
def require_license(feature=None):
|
|||
|
|
def decorator(f):
|
|||
|
|
@wraps(f)
|
|||
|
|
def wrapper(*args, **kwargs):
|
|||
|
|
status = current_app.server.license_status # 假设注入到 app 上下文
|
|||
|
|
if not status.valid:
|
|||
|
|
return jsonify({'success': False, 'error': status.message}), 403
|
|||
|
|
if feature and not status.features.get(feature, True):
|
|||
|
|
return jsonify({'success': False, 'error': f'未授权功能: {feature}'}), 403
|
|||
|
|
return f(*args, **kwargs)
|
|||
|
|
return wrapper
|
|||
|
|
return decorator
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 运行与配置
|
|||
|
|
|
|||
|
|
- `config.ini`:
|
|||
|
|
```ini
|
|||
|
|
[LICENSE]
|
|||
|
|
path = D:/BodyCheck/License/license.json
|
|||
|
|
public_key = D:/BodyCheck/License/license_pub.pem
|
|||
|
|
grace_days = 7
|
|||
|
|
```
|
|||
|
|
- 授权文件放置:默认 `data/license.json`(开发环境),打包环境放置在 `exe` 同级 `data`。
|
|||
|
|
- 前端激活保存位置与读取与后端一致(通过 API 或直接写入文件)。
|
|||
|
|
|
|||
|
|
## 运维与发行
|
|||
|
|
|
|||
|
|
- 发行流程:
|
|||
|
|
1. 客户安装并启动软件,生成 `machine_id`。
|
|||
|
|
2. 客服/授权服务器生成签名授权文件(绑定 `machine_id`)。
|
|||
|
|
3. 客户端导入授权文件或在线激活自动拉取授权。
|
|||
|
|
- 续期与升级:
|
|||
|
|
- 续期生成新授权文件(同一 `license_id` 或新 ID),替换旧文件。
|
|||
|
|
- 新版本可通过 `version` 或 `features` 差异化控制功能包。
|
|||
|
|
- 撤销与黑名单(可选,在线):
|
|||
|
|
- 维护撤销列表并在在线校验时拒绝。
|
|||
|
|
|
|||
|
|
## 兼容与开发模式
|
|||
|
|
|
|||
|
|
- 开发/测试模式:
|
|||
|
|
- 允许通过环境变量或配置启用 `dev_mode`,免授权检查,仅限开发构建。
|
|||
|
|
- 生产打包时移除或加固该入口,避免被滥用。
|
|||
|
|
|
|||
|
|
## 风险与缓解
|
|||
|
|
|
|||
|
|
- 时间篡改:使用授权签发时间与过期时间 + 宽限期校验;可选在线时间校准。
|
|||
|
|
- 硬件变更:提供有限容差与人工重新授权流程。
|
|||
|
|
- 文件丢失:提示恢复授权或联系支持,保留试用/降级模式保障基本可用。
|
|||
|
|
|
|||
|
|
## 里程碑与落地计划(建议)
|
|||
|
|
|
|||
|
|
1. 新增 `license_manager.py` 与后端集成(校验、装饰器、状态注入)
|
|||
|
|
2. 在 `main.py` 中接入授权校验,限制关键 API
|
|||
|
|
3. 前端新增激活页与状态展示(在线/离线两个流程)
|
|||
|
|
4. 授权服务器与私钥管理上线(可选轻量版)
|
|||
|
|
5. 运维流程与支持文档完善(续期、撤销、迁移)
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
如需,我可以直接在代码库中新增 `license_manager.py` 与 `main.py` 的集成改造示例,及前端激活页的基本骨架。
|