caiyun / license-client
Caiyun commercial license client for Laravel
Requires
- php: ^8.3
- ext-json: *
- ext-openssl: *
- illuminate/console: ^12.0|^13.0
- illuminate/contracts: ^12.0|^13.0
- illuminate/http: ^12.0|^13.0
- illuminate/routing: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- nesbot/carbon: ^3.0
- symfony/http-foundation: ^7.2|^8.0
- symfony/http-kernel: ^7.2|^8.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.0
- mockery/mockery: ^1.6
- orchestra/testbench: ^10.0|^11.0
- phpunit/phpunit: ^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Laravel 商业授权客户端,支持 RSA 签名授权书(v2)、授权时间、域名绑定、功能权益、远程撤销和离线宽限。
安装
在业务项目的 composer.json 配置私有仓库:
{
"repositories": [
{"type": "vcs", "url": "git@github.com:763606865/caiyun-license-client.git"}
]
}
composer require caiyun/license-client:^1.0 php artisan vendor:publish --tag=caiyun-license-config
Laravel 会通过 Composer 自动发现 LicenseServiceProvider,自动注册 licensed、feature 中间件和 license:status 命令。默认将基础授权中间件加入 web 和 api 组。
配置(授权书模式)
被授权方推荐只配置:
LICENSE_ENABLED=true LICENSE_SERVER_URL=https://license.example.com LICENSE_FILE=/path/to/LIC-xxxx.license LICENSE_PUBLIC_KEY_PATH=/path/to/public.pem
- 在管理后台「授权包管理」下载
.license授权书,连同public.pem通过安全渠道交付。 - 将授权书放到
LICENSE_FILE指定路径(默认storage/license/caiyun.license)。 Client ID/Client Secret、有效期、域名、功能权益、默认核验路径均写在授权书内,客户端自动解析,无需再逐项写入 env。
公钥也可改用 LICENSE_PUBLIC_KEY(Base64 编码的 PEM)。私钥只能保留在授权服务器。
可选高级项:
LICENSE_GLOBAL_MIDDLEWARE=true LICENSE_VERIFY_DOMAIN=true LICENSE_REMOTE_ENABLED=true LICENSE_REMOTE_CHECK_INTERVAL=60 LICENSE_OFFLINE_GRACE_HOURS=72 LICENSE_HEARTBEAT_SCHEDULE_ENABLED=true LICENSE_HEARTBEAT_SCHEDULE_AT=01:00
配置了 LICENSE_SERVER_URL 时默认开启远程校验。仍可用 LICENSE_TOKEN / LICENSE_REMOTE_ENDPOINT / LICENSE_OPENAPI_CLIENT_* 覆盖(兼容旧部署)。
php artisan license:status --domain=example.com php artisan license:verify --domain=example.com
启用远程授权后,包会默认每天 01:00 调度 license:verify 主动上报心跳。服务器仍需正常运行 Laravel Scheduler:
* * * * * cd /path/to/current && php artisan schedule:run >> /dev/null 2>&1
功能授权
Route::middleware('feature:payment')->group(function (): void { Route::post('/orders/{order}/pay', PayController::class); });
模块内部也应进行权益检查,避免只删除路由中间件即可绕过:
use Caiyun\License\LicenseManager; app(LicenseManager::class)->authorize('payment', request()->getHost());
新功能在发布包前加入 config/license.php 的 features。
授权书格式(v2)
三段式 header.payload.signature(Base64URL),对 header.payload 做 RSA-SHA256 签名。
Header:
{ "typ": "caiyun-license", "alg": "RS256", "v": 2 }
Payload 主要字段:license_id、customer、plan、project、有效期、features、domains、openapi.client_id / openapi.client_secret、endpoints.lease_valid。
远程租约协议
客户端使用授权书中的 OpenAPI Client Secret,对请求自动执行 AES-256-GCM 加密和 HMAC-SHA256 签名。加密前的业务数据为:
{
"license": "<signed-license-v2>",
"license_id": "LIC-2026-0001",
"instance_id": "stable UUID",
"domain": "example.com",
"project": "cms",
"app_version": null
}
授权服务器返回:
{
"code": 200,
"data": { "lease": "<signed-lease>" }
}
租约 Payload 必须包含:
{
"license_id": "LIC-2026-0001",
"instance_id": "stable UUID",
"domain": "example.com",
"issued_at": "2026-08-04T12:00:00+08:00",
"expires_at": "2026-08-07T12:00:00+08:00",
"features": ["payment", "mobile", "ai"]
}
租约使用同一 RSA 私钥签名(两段式),有效时间不得超过 LICENSE_OFFLINE_GRACE_HOURS。撤销返回 HTTP 403:
{"code":403,"reason":"revoked","message":"授权已撤销"}
授权书含调用密钥,泄露后应立即在后台轮换 Secret 并重新下载下发。
开发
composer install composer check
PHP 要求 >= 8.3,支持 Laravel 12 和 Laravel 13。
License
Proprietary. 未经授权不得复制、修改、再分发或绕过许可验证。