概述
API基础信息
Base URL: https://yanzheng.6vps.net/api
请求方式: POST
数据格式: JSON
字符编码: UTF-8
{
"code": 1,
"msg": "操作成功",
"data": {}
}
参数说明:
code: 状态码,1表示成功,0表示失败,-1表示特殊错误msg: 提示信息data: 返回数据(部分接口有)
Token机制
一次性短期凭证,更安全更快速
卡密登录
使用卡密进行软件验证
试用登录
免费试用软件功能
自主解绑
自主解绑旧设备标识
获取公告
查看系统公告信息
卡密心跳
定期验证卡密状态,防止破解
安全机制
了解API的安全验证机制
版本更新
版本强制更新机制说明
错误码说明
查看所有错误码及其含义
安全机制
为了防止API被破解和滥用,系统实现了以下安全机制:
- 请求签名验证:所有API请求必须包含HMAC-SHA256签名,防止请求被篡改和伪造
- 时间戳验证:请求必须包含时间戳,服务端验证时间戳有效性(±5分钟),防止重放攻击
- 随机数验证:请求必须包含随机数(nonce),服务端缓存已使用的nonce,防止重复请求
- 卡密验证:所有需要卡密的接口都需要验证卡密的有效性
- 卡密状态检查:每次请求都会检查卡密是否已激活、是否到期
- 安全日志记录:记录所有安全相关事件,方便追踪异常行为
- 速率限制:对登录接口实施IP维度速率限制,防止暴力破解
- 高频封禁:高频无效请求将触发临时封禁
- 白名单机制:白名单IP可以跳过所有安全验证,方便开发调试
- 黑名单机制:黑名单IP将被直接拒绝访问,无法调用任何API
- 版本强制校验:登录接口(卡密登录、试用登录)必须包含version参数,服务端校验版本是否低于最低要求,防止旧版软件绕过安全更新
所有API请求必须包含以下安全参数:
- timestamp:当前时间戳(秒),服务端会验证时间戳是否在有效范围内(±5分钟)
- nonce:随机字符串(建议使用UUID或MD5),服务端会缓存已使用的nonce,防止重复请求
- sign:HMAC-SHA256签名,使用软件的app_secret作为密钥
签名生成步骤:
- 将所有请求参数(除sign外)按参数名升序排序
- 将排序后的参数拼接成查询字符串(如:card_no=xxx&device_id=xxx&nonce=xxx&software_id=xxx×tamp=xxx&version=xxx)
- 使用HMAC-SHA256算法,以app_secret为密钥,对拼接字符串进行签名
- 将签名结果作为sign参数的值
示例代码(PHP):
function generateSign($params, $secret) {
unset($params['sign']);
ksort($params);
$string = http_build_query($params);
return hash_hmac('sha256', $string, $secret);
}
$params = [
'card_no' => 'FTPM-O0DX-5IN8-AZKR',
'nonce' => md5(uniqid(mt_rand(), true)),
'software_id' => 2,
'timestamp' => time(),
'version' => '1.0.0' // 登录接口必须包含 version
];
$secret = 'test_secret_key_123456';
$sign = generateSign($params, $secret);
$params['sign'] = $sign;
// 发送请求
$json = json_encode($params);
// ... 使用curl等工具发送请求
- 激活卡密:通过卡密登录接口激活卡密,卡密状态变为已使用
- 卡密有效期:卡密激活后开始计算有效期,到期后无法继续使用
- 卡密使用:所有需要卡密的接口都需要携带card_no和software_id参数
- 卡密唯一性:每张卡密只能使用一次,使用后无法重复使用
- 强制HTTPS:所有API请求必须使用HTTPS协议,禁止使用HTTP
- 请求方式:所有接口仅支持POST请求,参数通过JSON格式放在请求体中
- 禁止GET请求:卡密信息严禁出现在URL中,避免被服务器日志记录
- 卡密保护:客户端应妥善保管卡密,避免在日志、错误信息中泄露
- device_id用途:用于软件启用设备绑定功能时,限制卡密只能在指定设备上使用
- 生成规范:建议基于硬件指纹(如MAC地址、CPU序列号等)生成唯一标识
- 服务端校验:服务端会校验device_id的格式和长度,防止伪造
- 绑定限制:同一卡密只能绑定一个device_id,更换设备需重新激活
系统支持IP白名单和黑名单功能,用于精细化的访问控制:
白名单功能
- 跳过安全验证:白名单IP可以跳过签名、时间戳、随机数和速率限制验证
- 开发调试:方便开发人员在不实现完整签名机制的情况下测试API
- 内部系统:内部服务器可以直接访问API,无需复杂的签名流程
- 设备绑定:白名单规则支持按设备ID进行更精细的控制
黑名单功能
- 拒绝访问:黑名单IP将被直接拒绝访问,无法调用任何API
- 封禁恶意用户:将恶意IP加入黑名单,防止攻击
- 设备绑定:黑名单规则也支持按设备ID进行更精细的控制
验证优先级
- 首先检查黑名单,如果IP在黑名单中,直接拒绝访问
- 然后检查白名单,如果IP在白名单中,跳过所有安全验证
- 如果IP既不在白名单也不在黑名单,执行所有安全验证
白名单请求示例
白名单IP可以简化请求参数,无需签名、时间戳和随机数:
{
"software_id": 2,
"card_no": "TEST-1234567890",
"device_id": "DEVICE_001"
}
注意:白名单功能需要在后台管理系统中配置,由管理员添加IP地址到白名单。
版本强制更新机制
版本强制更新是一项重要的安全机制,通过在后台设置最低允许版本,强制要求客户端必须升级到指定版本才能继续使用软件,防止旧版本软件绕过安全更新。
1. 后台配置
管理员在后台的"软件管理"中可以设置:
- 最低允许版本(min_version):如
1.0.0,低于此版本的客户端将被拒绝 - 最新版本(latest_version):如
2.5.0,用于提示用户最新版本号 - 下载地址(download_url):新版本的下载链接
2. 客户端请求
客户端在调用登录接口(卡密登录、试用登录)时,必须在请求参数中包含 version 字段:
{
"software_id": 1,
"version": "1.2.0", // 客户端当前版本号
"card_no": "XXXX-XXXX-XXXX-XXXX",
"timestamp": 1737494400,
"nonce": "random_string",
"sign": "hmac_sha256_signature"
}
3. 服务端校验
服务端会自动比较客户端版本号与最低允许版本:
- 如果
客户端版本 >= 最低允许版本:正常处理请求 - 如果
客户端版本 < 最低允许版本:返回强制更新响应(code=100)
当客户端版本过低时,登录接口(卡密登录、试用登录)会返回以下响应:
{
"code": 100, // 特殊状态码,表示强制更新
"msg": "当前版本过低,请更新后使用",
"data": {
"min_version": "2.0.0", // 最低允许版本
"latest_version": "2.5.0", // 最新版本
"download_url": "https://example.com/download/v2.5.0" // 下载地址
}
}
客户端处理建议:
- 检测到
code == 100时,立即弹窗提示用户版本过低 - 禁止用户继续使用软件,直到完成更新
- 提供"立即更新"按钮,点击后打开
download_url - 显示最新版本号,提示用户当前版本与最新版本的差距
版本号必须遵循语义化版本(Semantic Versioning)规范:
标准格式:主版本号.次版本号.修订号
- 主版本号(Major):重大功能变更或不兼容的API修改,如
1.x.x→2.x.x - 次版本号(Minor):新增功能,但向后兼容,如
2.0.x→2.1.x - 修订号(Patch):bug修复,如
2.1.0→2.1.1
示例:
1.0.0 // 初始版本
1.0.1 // 修复了一些bug
1.1.0 // 新增了部分功能
2.0.0 // 重大升级,可能不兼容旧版
版本比较规则:
2.5.0>2.0.02.0.1>2.0.010.0.0>9.9.9(数值比较,不是字符串比较)
当客户端检测到API返回的 code == 100 时,应该:
- 立即弹窗提示:告知用户当前版本过低,需要更新
- 禁止继续使用:直到完成更新后才能使用软件
- 提供更新按钮:点击后打开
data.download_url下载页面 - 显示版本信息:展示最低要求版本和最新版本号
- 强制退出:如果用户拒绝更新,应退出程序
响应结构示例:
{
"code": 100,
"msg": "当前版本过低,请更新后使用",
"data": {
"min_version": "2.0.0",
"latest_version": "2.5.0",
"download_url": "https://example.com/download/v2.5.0"
}
}
- 强制执行:客户端必须严格处理 code=100 的情况,不能让用户绕过更新继续使用
- 只在登录时检查:系统只在登录接口(卡密登录、试用登录)进行版本检查,其他接口无需携带version参数
- 渐进式更新:建议先设置一个缓冲期,给用户足够时间更新,避免突然强制导致用户流失
- 测试验证:在生产环境修改最低版本前,务必在测试环境充分测试
- 回滚准备:保留回滚能力,如果新版本有问题,可以快速降低最低版本要求
- 安全漏洞修复:发现严重安全漏洞时,强制所有用户更新到安全版本
- API接口变更:当API接口发生不兼容变更时,要求客户端升级
- 功能废弃:当某些旧功能被废弃时,要求用户升级到新版本
- 协议升级:当通信协议或加密算法升级时,强制客户端同步升级
- 合规要求:满足法律法规要求,确保所有用户使用合规版本
Token机制详解
Token机制是本系统的核心安全特性,专门用于远程变量访问。它通过“一次性短期凭证”的方式,大幅提升了系统安全性。
传统方式的问题:
- 每次请求都需要传输卡密信息
- 卡密暴露风险高,容易被拦截
- 网络报文被抓包后可以长期复用
Token方式的优势:
- 卡密只在获取Token时传输一次
- Token有效期极短(60秒),即使被窃取也很快失效
- Token一次性使用,无法重放攻击
- 即使黑客拦截Token,也无法知道真实卡密
第一步:换取Token
客户端 服务器
│ │
│ POST /api/token/getToken │
│ {卡密 + 签名} │
├────────────────────────▶│
│ │ ① 验证签名
│ │ ② 验证卡密有效性
│ │ ③ 生成Token(60秒有效)
│ │ ④ 存储到Redis+MySQL
│ │
│ 返回Token │
│◀────────────────────────┤
│ {token: "abc123..."} │
第二步:使用Token获取变量
客户端 服务器
│ │
│ POST /remote_var/getVarByToken
│ {token + var_key} │
├────────────────────────▶│
│ │ ① 从 Redis 验证Token
│ │ ② 检查是否已使用
│ │ ③ 检查是否过期
│ │ ④ 标记为已使用
│ │ ⑤ 返回变量值
│ │
│ 返回变量值 │
│◀────────────────────────┤
│ {var_value: "..."} │
│ │
│ ⚠️ Token已失效 │
│ 需要重新获取 │
1、极短有效期:60秒
- Token生成后只有60秒有效期
- 超过60秒后自动失效,无法使用
- 即使被黑客窃取,也只有不到60秒的窗口期
2、一次性使用
- 每个Token只能使用一次
- 使用后立即标记为已使用,从 Redis 中删除
- 再次使用相同Token会返回“Token已失效”错误
- 如需获取多个变量,必须每次都重新获取Token
3、安全隔离
- 卡密信息只在获取Token时传输一次
- 后续远程变量请求只使用Token,不再需要卡密
- 即使变量请求被监听,也无法获取真实卡密
4、Redis加速 新
- Token存储采用 MySQL + Redis 双存储
- Token验证优先从 Redis 读取,响应速度提升 3.6倍
- Redis 不可用时自动降级到 MySQL,不影响功能
第一步:获取Token
调用 /api/token/getToken 接口,传入卡密和签名参数,获取一个60秒有效的Token。
第二步:使用Token访问变量
有两种方式:
- 方式1:获取单个变量:调用
/api/remote_var/getVarByToken,传入token和var_key - 方式2:获取所有变量(推荐):调用
/api/remote_var/getAllVarsByToken,一次性获取所有变量
注意事项:
- Token只能使用一次,使用后立即失效
- Token有效期为60秒,超时后自动失效
- 如需获取多个变量,建议使用
getAllVarsByToken一次性获取 - 获取Token后应立即使用,不要延迟
Q1:为什么Token只能使用一次?
A:一次性使用是重要的安全机制。即使黑客拦截Token,也无法重复使用进行攻击。如果需要获取多个变量,请使用 getAllVarsByToken 接口一次获取所有变量。
Q2:60秒会不会太短?
A:60秒对于正常使用已经足够。获取Token后应立即使用,整个过程通常不超过1秒。
Q3:什么时候需要获取Token?
A:只有当您需要访问远程变量时才需要Token。其他接口(如卡密登录、心跳)不需要Token。
Q4:旧的卡密直接访问方式还能用吗?
A:可以,系统保留了向后兼容。但强烈建议升级到Token方式,安全性更高且性能更好。
- 立即使用:获取Token后应立即使用,不要延迟
- 不要缓存Token:不要将Token存储在本地,每次都重新获取
- 错误处理:Token失效时自动重新获取,不要无限重试
- HTTPS传输:生产环境必须使用HTTPS,防止Token被窃听
- 批量获取:如需多个变量,使用
getAllVarsByToken一次获取所有
Token接口
1. 获取Token 需签名
| 接口地址 | /api/token/getToken | ||||||||||||||||||||||||
| 请求方式 | POST | ||||||||||||||||||||||||
| 请求格式 | JSON(Content-Type: application/json) | ||||||||||||||||||||||||
| 传输协议 | 必须使用HTTPS | ||||||||||||||||||||||||
| 请求参数 |
|
||||||||||||||||||||||||
| 请求示例 | |
||||||||||||||||||||||||
| 返回示例 | |
||||||||||||||||||||||||
| 错误码 |
1 成功 0 参数错误 / 卡密不存在 / 卡密未激活 / 卡密已过期 / 签名验证失败 / 系统错误 |
需要已激活的卡密才能调用
Token有效期为60秒,超时后自动失效
每个Token只能使用一次,使用后立即失效
2. 使用Token获取指定变量 无需签名 Redis加速
| 接口地址 | /api/remote_var/getVarByToken | ||||||||||||
| 请求方式 | POST | ||||||||||||
| 请求格式 | JSON(Content-Type: application/json) | ||||||||||||
| 传输协议 | 必须使用HTTPS | ||||||||||||
| 请求参数 |
|
||||||||||||
| 请求示例 | |
||||||||||||
| 返回示例 | |
||||||||||||
| 错误码 |
1 成功 0 参数错误 / Token不存在 / Token已使用 / Token已过期 / 变量不存在 / 系统错误 |
Redis缓存加速:Token验证优先从 Redis 读取,响应时间减少 72.5%
容灾机制:Redis 不可用时自动降级到 MySQL,不影响功能
无需签名:使用Token的接口不需要传送 timestamp、nonce、sign 参数
一次性使用:Token使用后立即失效,再次使用会返回错误
3. 使用Token获取所有变量 无需签名 Redis加速 推荐
| 接口地址 | /api/remote_var/getAllVarsByToken | ||||||||
| 请求方式 | POST | ||||||||
| 请求格式 | JSON(Content-Type: application/json) | ||||||||
| 传输协议 | 必须使用HTTPS | ||||||||
| 请求参数 |
|
||||||||
| 请求示例 | |
||||||||
| 返回示例 | |
||||||||
| 错误码 |
1 成功 0 参数错误 / Token不存在 / Token已使用 / Token已过期 / 系统错误 |
1、一次获取所有:只需一个Token,就能获取所有远程变量
2、减少请求次数:不用为每个变量都单独请求
3、性能更好:批量读取效率更高,减少网络开销
返回所有启用的远程变量
如果只需要单个变量,使用 getVarByToken 即可
公告接口
1. 获取公告列表 公开接口
| 接口地址 | /api/announcement/getList | ||||||||
| 请求方式 | POST | ||||||||
| 请求格式 | JSON(Content-Type: application/json) | ||||||||
| 传输协议 | 必须使用HTTPS | ||||||||
| 请求参数 |
|
||||||||
| 请求示例 | |
||||||||
| 返回示例 | |
||||||||
| 错误码 |
1 成功 0 非法请求 / 系统错误 |
- 全局公告:不传software_id或传0时,获取全局公告,所有软件都能看到
- 软件公告:传递software_id时,只获取该软件的公告
- 公告类型:返回的type字段表示公告类型(0=普通,1=重要,2=紧急)
- 排序规则:公告按sort降序、ID降序返回,sort越大越靠前
- 状态过滤:只返回启用状态的公告
- 无需签名:此接口不需要签名验证,可以直接调用
- 缓存建议:建议客户端缓存公告数据,避免频繁请求
- 更新频率:建议每次启动软件时调用一次,或每隔一段时间调用一次
- 显示建议:建议根据type字段使用不同颜色或图标显示公告
用户接口
1. 卡密登录 无需登录
| 接口地址 | /api/user/loginByCard | ||||||||||||||||||||||||||||||||
| 请求方式 | POST | ||||||||||||||||||||||||||||||||
| 请求格式 | JSON(Content-Type: application/json) | ||||||||||||||||||||||||||||||||
| 传输协议 | 必须使用HTTPS | ||||||||||||||||||||||||||||||||
| 请求参数 |
|
||||||||||||||||||||||||||||||||
| 请求示例 | |
||||||||||||||||||||||||||||||||
| 返回示例 | |
||||||||||||||||||||||||||||||||
| 错误码 |
1 成功 100 版本过低,强制更新 0 参数错误 / 软件不存在或已禁用 / 卡密不存在或已被使用 / 系统错误 |
- 使用卡密登录会激活卡密,卡密状态变为已使用
- 卡密只能使用一次,使用后自动标记为已使用
- 登录成功后会返回到期时间信息
- 如果软件启用了设备绑定,则必须传递device_id
3. 试用登录 需设备标识
| 接口地址 | /api/user/trial | ||||||||||||||||||||||||||||
| 请求方式 | POST | ||||||||||||||||||||||||||||
| 请求格式 | JSON(Content-Type: application/json) | ||||||||||||||||||||||||||||
| 传输协议 | 必须使用HTTPS | ||||||||||||||||||||||||||||
| 请求参数 |
|
||||||||||||||||||||||||||||
| 请求示例 | |
||||||||||||||||||||||||||||
| 返回示例 | |
||||||||||||||||||||||||||||
| 错误码 |
1 成功 100 版本过低,强制更新 0 参数错误 / 软件不存在或已禁用 / 该软件不提供试用 / 请传递设备标识 / 该设备已试用过 / 系统错误 |
- 试用时长:试用时长由软件的trial_minutes配置决定,单位为分钟
- 试用限制:如果软件启用了试用限制(trial_limit=1),则每个设备只能试用一次
- 试用缓存:试用信息会缓存在服务端,试用期内重复调用会返回相同的试用信息
- 试用到期:试用到期后需要购买正式版卡密才能继续使用
- 设备绑定:如果软件启用了设备绑定,则必须传递device_id参数
- 试用提示:返回的trial_notice字段可用于在软件中显示试用到期提示
- 试用次数限制:试用次数由软件的trial_limit配置决定,0表示不限制,1表示限制一次
- 试用时间计算:试用时间从第一次调用试用接口开始计算,到期后无法再次试用
- 设备标识:device_id用于区分不同设备,建议使用硬件指纹生成唯一标识
- 缓存过期:试用信息缓存时间与试用时长相同,到期后自动清除
5. 自主解绑设备 需扣除时长
| 接口地址 | /api/user/unbindDevice | ||||||||||||||||||||||||||||
| 请求方式 | POST | ||||||||||||||||||||||||||||
| 请求参数 |
|
||||||||||||||||||||||||||||
| 返回示例 | |
- 自助解绑:允许用户在更换电脑后,通过接口自主解除旧设备的绑定。
- 扣费机制:根据后台设置,每次解绑会扣除相应的天数或分钟数作为手续费。
- 次数限制:后台可限制每个卡密每月最多解绑的次数。
- 类型限制:后台可以在卡密类型中设置是否允许自助解绑,部分类型可能不允许使用此功能。
4. 卡密心跳 安全
| 接口地址 | /api/user/heartbeat | ||||||||||||||||||||||||||||
| 请求方式 | POST | ||||||||||||||||||||||||||||
| 请求格式 | JSON(Content-Type: application/json) | ||||||||||||||||||||||||||||
| 传输协议 | 必须使用HTTPS | ||||||||||||||||||||||||||||
| 请求参数 |
|
||||||||||||||||||||||||||||
| 请求示例 | |
||||||||||||||||||||||||||||
| 返回示例 | |
||||||||||||||||||||||||||||
| 错误码 |
1 成功 0 参数错误 / 卡密不存在或未激活 / 卡密已到期 / 系统错误 |
防止卡密滥用和破解:心跳接口是系统安全机制的重要组成部分,用于定期检查卡密是否合法
- 验证卡密状态:每次心跳都会检查卡密是否已激活、是否到期
- 防止破解:定期验证确保只有合法的卡密才能继续使用软件
- 实时状态同步:返回最新的卡密状态信息(到期时间等)
调用建议:建议每隔30-60秒调用一次,确保及时发现卡密状态变化
错误码说明
| 错误码 | 说明 |
|---|---|
| 1 | 操作成功 |
| 0 | 参数错误 / 软件不存在或已禁用 / 卡密不存在或已被使用 / 卡密已到期 / 变量不存在 / 非法请求 / 系统错误 |
- code = 1:表示请求成功,返回的数据在data字段中
- code = 0:表示请求失败,msg字段会包含具体的错误信息
注意事项
- 所有需要卡密的接口都必须传递正确的card_no和software_id
- 建议客户端实现自动重试机制,处理网络异常情况
- 心跳接口应该定期调用,建议间隔30-60秒
- 卡密只能使用一次,使用后自动标记为已使用,无法重复使用
- 卡密登录后会激活卡密,卡密状态变为已使用
- 必须使用HTTPS:所有API请求必须使用HTTPS协议,确保数据传输安全
- 卡密存储:建议在客户端安全存储卡密(如使用加密存储),避免明文保存
- 心跳超时检测:如果心跳失败超过一定次数,应该提示用户重新输入卡密
- 日志安全:记录API调用日志时,避免记录完整的卡密信息
- 输入验证:在客户端实现卡密格式验证,避免无效请求
- 用户体验:建议在客户端显示卡密到期时间信息
- 错误处理:妥善处理网络错误和API错误,避免泄露敏感信息
- 卡密登录:使用卡密号和软件ID调用登录接口(必须HTTPS)
- 获取信息:登录成功后会返回到期时间信息
- 心跳检测:定期调用心跳接口,验证卡密状态(建议30-60秒)
- 获取变量:根据需要调用远程变量接口获取配置
- 错误处理:如果返回code=0且提示卡密已到期,需要提示用户重新输入卡密
- 禁止HTTP:严禁使用HTTP协议传输卡密信息
- 禁止GET请求:严禁通过URL参数传递卡密
- 禁止日志泄露:严禁在客户端日志、错误信息中记录完整卡密
- 禁止暴力破解:严禁通过自动化工具批量尝试卡密
- 禁止多设备共享:严禁将同一卡密在多个设备上同时使用