快速入门
5分钟完成集成,开始验证授权
授权管理
查看授权、绑定域名、到期续期
一键授权打包
上传 ZIP,自动注入 SDK 并加密
API 参考
完整的 REST API 接口文档
代码加密
AES-256-GCM 加密方案
客户端 SDK 多平台
WP / 通用适配,手动集成指南
加密配额
月加密次数与 VIP 权益说明
完整安装指南
从零开始的部署教程
常见问题
授权验证常见问题解答
定时任务
配置 Cron 自动备份、邮件与打包队列
错误处理与安全
生产环境错误隔离与文件保护
Loader 下载限流
Nginx 部署让限流真正生效
快速入门
1. 获取授权码
在 产品页面 购买授权,或在控制台中获取已购授权的授权码。
2. 验证授权
使用 HTTP GET 请求验证授权:
curl "https://你的域名/api/verify?license_key=ZFS-XXXX-XXXX&domain=example.com&product_code=my-product"
3. 处理响应
验证成功返回 JWT Token 格式的响应:
{
"verified": true,
"license_id": "LIC-XXXX",
"product_code": "my-product",
"expires_at": "2026-12-31",
"token": "eyJhbGciOiJSUzI1NiIs..."
}
授权管理
购买授权后,你可以在控制台查看与管理自己的所有授权。
查看授权
进入「我的授权」页面,可看到全部授权及其状态:有效 / 试用中 / 已过期 / 无效,以及到期时间与最大绑定域名数。
域名管理
进入「域名管理」页面,按产品分组查看每个授权已绑定的域名,支持添加与删除绑定域名(删除需输入域名二次确认)。可绑定数量受产品设置与系统配置约束(默认 3 个)。
到期与续期
授权到期后将无法通过验证。到期前可在对应授权中查看剩余天数,并按提示续期或升级。
一键授权打包
上传项目 ZIP -> 自动注入 SDK -> 加密 -> 下载,无需写一行代码
1. 上传项目 ZIP
在管理后台选择产品,上传你的 PHP 项目 ZIP 文件。
2. 自动注入 + 加密
系统自动检测开发平台,注入授权配置和 Guard 保护调用,可选开启 AES-256-GCM 加密。
3. 下载分发
打包产物包含加密代码 + License 文件 + Loader 安装说明,交给客户部署即可。
API 参考
GET /api/verify
验证授权(主要端点)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
license_key | string | 是 | 授权码 |
domain | string | 否 | 绑定域名 |
ip | string | 否 | 客户端 IP |
product_code | string | 是 | 产品代码 |
返回: verified, token (JWT), expires_at, domain
POST /api/refresh
刷新 JWT Token(需 Authorization: Bearer header)
返回: token (新 JWT)
GET /api/key/{kid}
获取公钥(客户端验签用)
路径参数: kid — 密钥 ID,返回 PEM 格式公钥
GET /api/check-revoked
查询授权是否被吊销(需有效 token)
GET /api/health
健康检查(监控用)
代码加密
AES-256-GCM 认证加密 + C 扩展运行时解密,让代码固若金汤
| 特性 | 说明 |
|---|---|
| 加密算法 | AES-256-GCM 认证加密(防篡改) |
| 密钥派生 | PBKDF2-SHA256,10万次迭代,每文件独立随机盐 |
| 文件格式 | ZFSE 加密头 + 密文(头部为定长二进制元数据) |
| License 保护 | RSA-SHA256 签名,支持域名绑定和过期控制 |
| 运行时解密 | C 扩展 Hook 编译流程,内存中解密,磁盘永为密文 |
| 反调试 | 检测调试器扩展,生产环境有调试器时拒绝执行 |
客户侧安装步骤
# 1. 安装 Loader 扩展(选择对应 PHP 版本)
cp zfshang_loader-php8.1.so $(php -r 'echo ini_get("extension_dir");')/zfshang_loader.so
echo 'extension=zfshang_loader' >> /www/server/php/81/etc/php.ini
# 2. 放置 License 文件到项目根目录
cp zf-license.dat /var/www/html/
# 3. 重启 PHP
systemctl restart php8.1-fpm
# 4. 验证
php -m | grep zfshang
客户端 SDK 与多平台支持
绝大多数用户使用「一键授权打包」即可,系统会自动注入合适的适配器并加密,无需手动集成。本节面向需要手动集成 SDK的场景(如已有项目、或需要更精细的控制)。
平台适配
| 适配器 | 适用场景 |
|---|---|
WpAdapter | WordPress 主题 / 插件,自动 Hook WP 生命周期 |
GenericAdapter | Laravel、ThinkPHP、原生 PHP 及其他框架 / standalone(需 ext-curl) |
手动集成步骤
# 1. 安装 SDK(Composer)
composer require zfshang/license-client
# 2. 在入口引入并初始化 Guard
require_once __DIR__ . '/vendor/autoload.php';
use ZfLicense\Guard;
Guard::protect('/path/to/zf-license.dat');
# 3. 激活(CLI,首次部署到客户站点时执行一次)
php zf-activate.php --license-key=ZFS-XXXX-XXXX --license-id=LIC-XXXX [--domain=example.com]
zf-activate.php 完成(Web 激活做了同源校验,跨站 POST 会被拒绝)。激活后立即生效,无需重启服务。授权码与授权 ID 填反时激活逻辑会容错尝试两种顺序。
完整接入与 API 详见 SDK 包内 sdk/zfshang-license-client/README.md。
加密配额
非 VIP 用户每月可加密次数有限(默认 5 次 / 月),配额按自然月(YYYYMM)重置。在加密页面可查看本月已用 / 剩余次数。
| 账户类型 | 月加密次数 | 可上传格式 | 单文件上限 |
|---|---|---|---|
| 普通用户 | 5 次 / 月 | .php | 500 KB |
| VIP | 不限 | .php / .zip | .php 5 MB / .zip 100 MB |
完整安装部署指南
⏰ 定时任务(Cron)部署
cron/ 目录下有 4 个后台脚本,仅允许 CLI 执行(每个脚本开头都有 PHP_SAPI !== 'cli' 守卫,通过 Web 访问会返回 403 Forbidden)。请使用站点 PHP 可执行文件的绝对路径配置 crontab(以下以宝塔默认路径为例,请替换为你自己的 php 路径与项目路径)。
| 脚本 | 作用 | 建议频率 |
|---|---|---|
cron/backup_database.php | 每日数据库自动备份 | 0 3 * * * |
cron/send_emails.php | 消费邮件队列(需开启异步邮件) | * * * * * |
cron/expiration_reminder.php | 授权到期前 30/7/1 天邮件提醒 | 0 4 * * * |
cron/process_package_queue.php | 处理「SDK 模式」打包队列 | * * * * * |
示例 crontab
# 替换为你的项目绝对路径与 php 可执行文件路径
PROJECT=/www/wwwroot/zfshang.cn
PHP=/www/server/php/81/bin/php
# 每日 03:00 数据库备份
0 3 * * * $PHP $PROJECT/cron/backup_database.php >> /dev/null 2>&1
# 每分钟:邮件队列 + 打包队列
* * * * * $PHP $PROJECT/cron/send_emails.php >> /dev/null 2>&1
* * * * * $PHP $PROJECT/cron/process_package_queue.php >> /dev/null 2>&1
# 每日 04:00 到期提醒
0 4 * * * $PHP $PROJECT/cron/expiration_reminder.php >> /dev/null 2>&1
process_package_queue.php 每次只处理 1 个任务,并写入 storage/package_queue_heartbeat 心跳文件,可据此监控 cron 是否在正常运行。
🛡️ 错误处理与安全
- 生产环境不暴露错误详情:
public/index.php捕获未处理异常后只记录日志(storage/logs/app.log),向用户返回通用public/500.html,绝不回显堆栈、SQL 或路径。 - 调试模式由环境变量
APP_DEBUG控制(默认关闭)。仅临时排查时设置APP_DEBUG=true(php-fpm / Docker 环境变量),排查完务必改回,否则会泄露错误详情。 config/database.php含数据库明文密码,位于public/之外;标准部署 Web 根目录指向public/,该文件不可被直接下载。参考install/nginx.conf.example,已对/config、/storage、/app做了deny all防御性拦截。
🔒 Loader 下载限流部署
后台「系统设置 → 下载设置」可配置每个 IP 在指定周期内的 Loader 可下载次数,防止 .so 被批量爬取。
但 Loader 文件默认放在 Web 根目录下,会被 Nginx 当作静态文件直接返回、不经过 PHP,
因此限流设置默认不会生效。需在本站点的 Nginx 配置中加一段规则,把 /downloads/loaders/ 交由 PHP 处理,限流才会真正运行。
① 添加 Nginx 规则
在站点 server { } 块内、与现有 PHP 处理段同级,加入:
location ^~ /downloads/loaders/ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_pass unix:/run/php/php8.1-fpm.sock; # 与你的 PHP-FPM socket 保持一致
}
② 重载 Nginx
nginx -t && systemctl reload nginx
③ 验证是否生效
用浏览器或 curl 访问一次 Loader 下载地址:
curl -I https://你的域名/downloads/loaders/zfshang_loader-php8.1.so
能正常返回 200 即说明请求已交给 PHP 处理;若用同一未登录 IP、且额度设为 1,快速第 2 次访问应返回 429 限流响应。
install/nginx.conf.example 的「Loader 下载」段。
常见问题
授权验证失败怎么办?
检查授权码是否正确、是否已过期、域名是否匹配。可在控制台查看授权状态。
如何更换绑定域名?
登录控制台,在对应授权中点击"域名管理",输入新域名即可。
API 调用频率限制是多少?
默认每 IP 每分钟 30 次验证请求。可在控制台绑定 IP 获得更高频率。
加密后的代码能破解吗?
AES-256-GCM 是目前最安全的对称加密算法之一,配合每文件独立密钥,破解一个文件不影响其他文件。
Loader 扩展需要额外付费吗?
ZFShang Loader 扩展完全免费,支持 PHP 7.4 ~ 8.3。
如何更换加密密钥?
在管理后台「代码加密」页面点击「轮换加密密钥」。注意:轮换后已加密的旧文件需重新打包。