跨项目集成指南:赞助版 / 许可证验证(可复制到任意 Web 项目)¶
本文是“可移植的实施手册”。你可以把这份文档连同你的项目上下文发给我,我能据此快速落地集成。文档覆盖了:架构、远程接口契约、机器码算法、DB 结构、后端与前端对接、宽限与容错、安全策略、测试与运维。
0. 集成目标与范围¶
- 为任意 Web 项目(Node/Express、NestJS、Django、Flask、SpringBoot、Go 等)集成“许可证验证 + 动态额度 + 宽限容错”的赞助版能力。
- 支持本地缓存 + 远程校验的“双层验证”,保证在远程服务抖动时不影响正常使用。
- 支持“设备绑定与切换”,阻止简单的“拔网线绕过”。
- 前端提供管理界面:激活、状态展示、手动刷新、设备切换、错误提示。
1. 总体架构¶
- 远程验证服务:
https://license.zhoujie218.top/ POST /api/license/verify:许可证校验POST /api/license/switch-device:设备切换- 本地后端(你的项目):
- 暴露:
POST /api/sponsor/activate、GET /api/sponsor/status、POST /api/sponsor/heartbeat、POST /api/sponsor/clear、POST /api/sponsor/device-switch-request、GET /api/sponsor/machine-id - 每日 3-5 点随机心跳一次
- 本地 DB 缓存:许可证、状态、错误日志、额度、上次校验时间
- 前端管理页:
- 激活表单(输入许可证) + “获取许可证”引导链接
- 状态卡片(版本、许可证、状态徽标、宽限提示、最近反馈)
- 远程详情区(许可证字段展示)
- 设备切换表单
2. 远程接口契约(固定,不要更改)¶
2.1 Verify(验证许可证)¶
- 方法:POST
https://license.zhoujie218.top/api/license/verify - 请求:
- 响应(成功示例):
{ "success": true, "message": "密钥验证成功", "license": { "licenseKey": "my-...", "applicationName": "密钥管理系统", "licenseTypeName": "终生赞助版", "licenseTypeDisplayName": "终生赞助版", "status": "active", "maxUses": 999999, "currentUses": 8, "maxDevices": 1, "currentDevices": 2, "customField1": "500", // 动态总额 "customField2": "100", // 动态批量 "customField3": "10", "expiresAt": "2125-07-16T08:29:19Z", "activatedAt": "2025-08-09 08:29:19", "timezone": "UTC", "clientIP": "1.2.3.4" }, "token": "optional-jwt-or-session" } -
响应(失败示例):
-
失败时 HTTP 可能返回 4xx/5xx,需要把状态码与消息一并透传到前端。
2.2 Switch Device(设备切换)¶
- 方法:POST
https://license.zhoujie218.top/api/license/switch-device - 请求:
- 响应:与 Verify 一致的成功/失败结构(
success布尔 + 消息 + 可选的 license/token)。
3. 机器码生成(跨语言可实现)¶
- 设计目标:同一台宿主/容器内稳定、升级/重启不变;迁移机器需显式切换,保证在同一台机器上,不同的容器也能机器码不变
- 建议特征:
- OS 平台(
os.platform()/uname) - CPU 核数与型号(
cpus.length、第一颗 CPU model) - 总内存(
totalmem) - OS 版本信息(release/version)
- 架构(
x64/arm64) - 主机名(hostname)
- 容器/虚拟化标识(cgroup、/proc、环境变量)
- 网络接口签名(接口名+MAC 聚合并排序)
- 实现:将以上键值排序后 JSON 序列化,计算 SHA-256 哈希,前缀
server_,保留前 16 字符。
4. 本地数据模型(建议表)¶
表名自定,以下为建议字段(与现有实现对齐,便于迁移): - license_key(唯一,TEXT) - machine_id(TEXT) - verification_token(TEXT) - status(TEXT:active/grace/grace_limited/expired/pending/switching) - remote_verified_at、local_verified_at(DATETIME) - last_remote_error_message、last_remote_error_http_status、last_remote_error_time(记录失败) - last_license_type_name(TEXT) - limit_total_licenses(INTEGER,远程 customField1) - limit_batch_count(INTEGER,远程 customField2) - consecutive_failures(INTEGER) - device_switch_requested_at、old_machine_id(DATETIME/TEXT)
可用任意 DB(SQLite/MySQL/Postgres)。重要的是:字段含义与流程一致,便于状态机计算与 UI 展示。
5. 本地状态机与宽限策略¶
- 信任期 trustDays(默认 7 天):最近成功后一定时间内完全信任。
- 宽限期 graceDays(默认 15 天):远程失败但曾成功激活时,进入宽限提示(所有功能不受限);倒计时以“最后一次失败时间”为起点,超期后回退为社区版。
grace_limited可选:若需要在宽限末期局部限流,可在业务层加入(例如批量生成上限=20)。
6. 动态额度与社区兜底¶
- 赞助版激活:
- 总量上限 =
customField1(整数,空或无表示无限) - 批量上限 =
customField2(整数,空或无表示无限) - 社区版兜底:
- 总量上限 200,批量上限 20
- 实施点:在实际“生成密钥/创建资源”的后端入口处统一检查额度(读取本地状态与缓存额度)。
7. 后端集成步骤(通用)¶
- 引入 HTTP 客户端与 DB 层(如 axios + ORM/原生驱动)。
- 实现机器码生成器。
- 创建赞助表(见 §4)。
- 实现“远程校验包装”:
- 成功:落库状态、额度、
last_license_type_name,清空错误; - 失败:记录
last_remote_error_*,累加consecutive_failures,返回结构化remoteError{httpStatus,data,message}; - 实现接口:
POST /api/sponsor/activate(入参licenseKey→ 远程 verify)GET /api/sponsor/status(仅读本地,不触发远程)POST /api/sponsor/heartbeat(凭本地license_key远程 verify)POST /api/sponsor/device-switch-request(可选)POST /api/sponsor/clear(删除本地记录,回退社区版)GET /api/sponsor/machine-id- 管理业务限额点:把“动态额度 / 社区兜底”并入总量与批量检查函数中。
- 定时任务:每日 3-5 点随机执行一次
heartbeat()(或业务合适时间窗口)。
8. 前端集成要点¶
- 页面模块:
- 状态卡:机器码、当前版本名(
last_license_type_name或社区版)、当前许可证、赞助状态、宽限提示(验证失败才显示)、最近一次刷新反馈(含 HTTP 码与时间)。 - 激活表单:提交后调用
/api/sponsor/activate,成功前置渲染远程详情,再调用GET /api/sponsor/status刷新状态。 - 设备切换:输入新机器码 + 原因,调用
/api/sponsor/device-switch-request。 - 手动刷新:调用
/api/sponsor/heartbeat。 - 交互准则:状态接口不触发远程;防止“刚展示的远程详情被刷新覆盖”。
- 提示文案:
- 未激活:显示“未激活”。
- 已激活但失败:显示“当前验证失败,请稍后刷新。已进入宽限期,还剩 N 天,期间所有功能不受影响,过后将回退到社区版。”
9. 安全策略与反绕过¶
- 绑定稳定机器码 + 设备切换流程,防止简单复制迁移。
- 宽限倒计时 + 每日自动心跳 → 防止“断网长期绕过”。
- 服务端强校验额度,前端仅展示;所有异常要记录到日志并落库。
- 接口均需鉴权(如 JWT + 管理员角色)。
10. 错误处理与可观测¶
- 远程调用错误统一结构化:
remoteError{httpStatus,data,message},并写入 DB。 - 前端展示“最近一次刷新反馈”。
- 关键日志:激活成功/失败、心跳成功/失败、额度超限被拒绝。
11. 配置建议¶
SPONSOR_GRACE_TRUST_DAYS(默认 7)SPONSOR_GRACE_MAX_DAYS(默认 15)SPONSOR_MAX_CONSECUTIVE_FAILURES(默认 10)SPONSOR_DEVICE_SWITCH_WINDOW_HOURS(默认 24)SPONSOR_ALLOW_OFFLINE_TRUST(默认 true)远程 URL 建议硬编码(降低运维复杂性),如需多环境可在构建期切换。
12. 测试清单(可直接执行)¶
- 激活成功:展示远程详情;状态为“已激活”。
- 激活失败:提示远程失败原因;状态回落到最近本地评估;记录错误。
- 手动刷新成功/失败路径各一次,前端“最近一次刷新反馈”正确显示。
- 动态额度:当
customField1/2返回后,总量/批量检查生效;当为空时放开。 - 社区兜底:无许可证时总量=300,批量=20。
- 断网 1 天:仍可使用;显示宽限倒计时减少。
- 宽限到期:自动回退社区版;前端提示变化。
- 设备切换:旧→新机器码走通,旧机器受限。
- 清除许可证:回退社区版;状态与 UI 更新。
13. 交付与运维¶
- 日志:后端日志 + DB 中最近错误字段。
- 定时任务可靠性:心跳失败不抛死,记录警告并重排到次日。
- 备份:定期备份包含
sponsor_verification的 DB 文件。
14. 落地步骤(摘要)¶
- 第 1 步:落库(新增表或新增列)
- 第 2 步:接入机器码算法
- 第 3 步:实现远程校验包装
- 第 4 步:实现后端接口(activate/status/heartbeat/...)
- 第 5 步:在“生成关键资源”的入口合并额度检查
- 第 6 步:前端页面(状态卡、激活、刷新、切换)
- 第 7 步:部署定时心跳
- 第 8 步:联调与验收(按 §12 清单)
15. 附:可复用的接口返回结构(建议)¶
- 激活/心跳成功:
- 激活/心跳失败:
16. 我需要你提供的最小信息(便于我快速集成)¶
- 项目类型与语言(Node/Nest/Django/Flask/Spring/Go 等)
- 鉴权方式(JWT/Session)与管理端路由
- 你希望的额度策略(若需区别不同类型的赞助版)
- 现有数据库类型(SQLite/MySQL/Postgres)与迁移方式
- 需要覆盖的页面位置与样式偏好
- 部署环境(容器/物理机)、是否允许计划任务
准备好这些信息,把本指南与项目仓库/示例接口一并发给我,我即可在最短时间完成集成。