5.1 KiB
5.1 KiB
License Manager Go SDK 需求
背景
- 当前客户端 demo 直接对接服务端,集成复杂且不利于复用。
- 多个需要授权的产品希望以库的形式快速接入授权能力。
- 需要一个接口简洁、易于扩展、对调用方入侵极低的 Go SDK。
目标
- 封装授权激活、许可证校验、心跳续期等流程,减少业务方重复开发。
- 提供清晰的配置与生命周期管理,支持 CLI、服务和嵌入式场景。
- 兼容已有 License Manager 服务端接口,未来接口升级时对调用方透明。
- 支持在线 / 离线两种工作模式,满足联网和隔离环境的授权需求。
SDK 架构
| 模块 | 职责 |
|---|---|
license.Client |
SDK 入口,负责生命周期管理。 |
config |
统一的配置结构体,支持代码、环境变量、配置文件三种来源。 |
hardware |
硬件指纹采集,默认实现可被自定义扩展。 |
activation |
激活接口封装、授权码加载、许可证缓存。 |
validator |
对许可证内容、有效期、功能限制进行校验。 |
heartbeat |
心跳轮询、动态间隔调整、失败退避策略。 |
storage |
许可证加解密与本地持久化,支持自定义存储后端。 |
logger |
统一日志接口,默认输出到标准输出,可注入业务日志实现。 |
硬件指纹采集策略
- 标准组合指纹(默认):采集首个物理 MAC、CPU 型号、主机 ID,组合字符串后做哈希。
- 可插拔字段选择:调用方可通过配置决定纳入哪些硬件字段(如磁盘序列号、主板序列号等),SDK 保证字段顺序与哈希算法一致。
- 自定义采集器:提供
hardware.Provider接口,允许业务方完全自定义指纹生成逻辑(适配虚拟化、容器等环境)。 - 匿名化/脱敏模式:支持在上报前对字段进行额外哈希或加盐,满足隐私/合规要求。
- 实时采集策略:每次需要校验时即时采集,避免任何形式的本地缓存,以消除被复制或伪造的风险;若采集失败需有清晰的回退与错误提示。
核心功能需求
- 初始化
- 必填配置:服务端地址(离线模式可选)、产品标识、版本号、授权码来源或许可证文件路径、服务端 RSA 公钥(可通过路径或内容提供)。
- 可选配置:心跳间隔、超时、日志级别、硬件指纹采集策略、自定义 HTTP 客户端。
- 许可证加载与激活
- 在线模式:启动优先读取本地许可证;不存在或失效时自动激活,激活请求包含硬件指纹、产品信息、授权码,支持附加自定义字段。激活成功后自动校验并落盘,加解密沿用 AES-GCM;需使用配置中提供的 RSA 公钥验证服务端签名。
- 离线模式:仅校验本地许可证文件合法性(签名/有效期/硬件绑定),不访问网络;当本地许可证缺失或过期时返回明确错误,由业务方决定更新方式。需通过配置显式提供许可证文件路径(默认
license_code/license.lic可覆盖)及 RSA 公钥拷贝,保证可独立校验签名。
- 许可证校验
- 校验内容:签名/加密、有效期、硬件绑定、功能/限制字段。
- 提供同步 API(
Validate())供业务方在关键操作前主动检查。 - 提供只读访问接口(如
client.CurrentLicense()),可在业务运行时获取最新许可证的功能限制、配额等字段,便于执行业务级限制判断;当许可证更新时需即时刷新缓存并触发回调。
- 心跳服务
- 仅在在线模式启用:成功激活后自动启动,默认间隔 300s,可从服务器动态调整。
- 支持暂停/恢复接口,网络异常时指数退避并记录原因。
- 服务器返回新的许可证时自动替换并回调通知。
- 离线模式不启动心跳,SDK 需暴露显式 API 让业务层触发本地校验。
- 事件与回调
- 需支持
OnLicenseUpdated,OnHeartbeatError,OnActivationRequired等回调。 - 回调在独立 goroutine 执行,避免阻塞主流程。
- 需支持
- 错误处理
- 统一错误类型,区分可重试与不可重试场景。
- 提供错误码枚举,便于业务层按类型处理。
- 线程安全
- SDK 所有公开方法需并发安全,核心状态(许可证、心跳)内部加锁。
- 可测试性
- 对 HTTP、时间、硬件指纹、存储等外部依赖提供接口,方便 Mock。
使用方式
cfg := license.Config{
Server: "https://license.example.com",
Product: "edge-gateway",
Version: "2.3.1",
AuthCode: license.FromFile("license_code/authorization_code.txt"),
PublicKey: license.FromFile("license_code/rsa_public_key.pem"),
}
client, err := license.NewClient(cfg)
defer client.Close()
if err != nil { /* ... */ }
if err := client.Validate(context.Background()); err != nil {
// 业务自定义处理
}
交付物
- SDK 源码与 go.mod。
README:安装、Quick Start、常见问题。- 示例程序:最小化控制台示例 + 与现有 client-demo 等价的高级示例。