使用文档

时光授权系统文档

从快速开始到 API 对接,全面了解授权系统的使用与集成

对接示例

本章提供3 个完整场景的对接示例,从最简到最复杂,覆盖常见使用方式。

示例 1:最简单的"激活-使用"流程

适合:单功能插件,无复杂授权检查。

<?php
// my-plugin.php

if (!defined('ABSPATH')) exit;

define('LICENSE_SERVER', 'https://license.example.com');
define('PRODUCT_SLUG', 'my-plugin');
define('API_SECRET', 'your-secret');

// 1. 激活授权
add_action('admin_post_activate_license', function () {
    $key = sanitize_text_field($_POST['license_key'] ?? '');

    // 生成签名
    $domain = parse_url(home_url(), PHP_URL_HOST);
    $sign_data = $domain . '|' . $key . '|' . PRODUCT_SLUG . '|1';
    $signature = hash_hmac('sha256', $sign_data, API_SECRET);

    // 调用验证 API
    $response = wp_remote_post(LICENSE_SERVER . '/api/verify.php', [
        'body' => [
            'license_key' => $key,
            'domain' => $domain,
            'product' => PRODUCT_SLUG,
            'serial' => 1,
            'signature' => $signature,
        ],
    ]);

    $data = json_decode(wp_remote_retrieve_body($response), true);

    if ($data['status'] === 'success') {
        update_option('my_plugin_license', [
            'key' => $key,
            'info' => $data['data'],
            'time' => time(),
        ]);
        wp_redirect(admin_url('admin.php?page=my-plugin&activated=1'));
    } else {
        wp_redirect(admin_url('admin.php?page=my-plugin&error=' . urlencode($data['message'])));
    }
    exit;
});

// 2. 检查授权(带缓存)
function my_plugin_is_licensed() {
    $license = get_option('my_plugin_license', []);

    if (empty($license)) return false;

    // 缓存 7 天内有效
    if (time() - $license['time'] < 7 * 86400) {
        return true;
    }

    // 重新验证
    // ... 调用 API(同上)...
}

// 3. Gate 功能
add_action('admin_init', function () {
    if (!my_plugin_is_licensed() && isset($_GET['page']) && $_GET['page'] === 'my-plugin-feature') {
        wp_die('请先激活授权');
    }
});

示例 2:多域名 + 多产品授权管理

适合:插件作者自己运营多个插件,或需要给同一插件颁发多个站点的授权。

<?php

class MultiProductLicense {
    private $products = [
        'plugin-a' => ['name' => '插件 A', 'secret' => 'secret-aaaa'],
        'plugin-b' => ['name' => '插件 B', 'secret' => 'secret-bbbb'],
    ];

    public function activate($product_slug, $license_key) {
        if (!isset($this->products[$product_slug])) {
            return new WP_Error('invalid_product', '产品不存在');
        }

        $config = $this->products[$product_slug];
        $domain = $this->normalize_domain(home_url());
        $serial = 1;

        $sign_data = $domain . '|' . $license_key . '|' . $product_slug . '|' . $serial;
        $signature = hash_hmac('sha256', $sign_data, $config['secret']);

        $response = wp_remote_post('https://license.example.com/api/verify.php', [
            'body' => [
                'license_key' => $license_key,
                'domain' => $domain,
                'product' => $product_slug,
                'serial' => $serial,
                'signature' => $signature,
            ],
        ]);

        $data = json_decode(wp_remote_retrieve_body($response), true);
        if ($data['status'] !== 'success') {
            return new WP_Error('verify_failed', $data['message']);
        }

        // 保存到指定产品的 option
        update_option("my_plugin_{$product_slug}_license", [
            'key'  => $license_key,
            'info' => $data,
            'time' => time(),
        ]);

        return true;
    }

    public function check($product_slug) {
        $license = get_option("my_plugin_{$product_slug}_license", []);
        if (empty($license)) return false;

        // 7 天缓存
        if (time() - $license['time'] < 7 * 86400) return true;

        // 重新验证
        return $this->activate($product_slug, $license['key']) !== false;
    }

    private function normalize_domain($url) {
        $url = preg_replace('#^https?://#', '', $url);
        $url = preg_replace('#^www\.#', '', $url);
        $url = explode('/', $url)[0];
        return strtolower($url);
    }
}

// 使用
$license = new MultiProductLicense();
if (!$license->check('plugin-a')) {
    wp_die('插件 A 未授权');
}

示例 3:带试用期的 SaaS 授权

适合:首次安装给 7 天试用,过期后要求激活正式授权。

<?php

class TrialLicense {
    const TRIAL_DAYS = 7;

    public function get_status() {
        $license = get_option('my_plugin_license', null);

        if ($license && $license['status'] === 'active') {
            return [
                'type'   => 'licensed',
                'until'  => $license['expires_at'] ?? '永久',
            ];
        }

        // 检查试用期
        $installed_at = get_option('my_plugin_installed_at');
        if (!$installed_at) {
            $installed_at = time();
            update_option('my_plugin_installed_at', $installed_at);
        }

        $trial_end = $installed_at + self::TRIAL_DAYS * 86400;

        if (time() < $trial_end) {
            $remaining_days = ceil(($trial_end - time()) / 86400);
            return [
                'type'           => 'trial',
                'remaining_days' => $remaining_days,
            ];
        }

        return [
            'type'  => 'expired',
            'since' => $installed_at,
        ];
    }

    public function enforce() {
        $status = $this->get_status();
        if ($status['type'] === 'expired') {
            wp_die('试用期已结束,请购买正式授权');
        }
    }
}

// 每次加载插件时执行
$license = new TrialLicense();
$license->enforce();

测试工具

你可以用 cURL 测试 API 是否正常工作(无需 WordPress):

#!/bin/bash
# test_license.sh

LICENSE_KEY="LIC-XXXXX-XXXXX-XXXXX-XXXXX"
DOMAIN="www.example.com"
PRODUCT="my-plugin"
SERIAL=1

# 计算签名(与 PHP 一致)
SIGN_DATA="${DOMAIN}|${LICENSE_KEY}|${PRODUCT}|${SERIAL}"
SIGNATURE=$(echo -n "$SIGN_DATA" | openssl dgst -sha256 -hmac "your-api-secret" | awk '{print $2}')

# 发送请求
curl -X POST https://license.example.com/api/verify.php \
  -d "license_key=${LICENSE_KEY}" \
  -d "domain=${DOMAIN}" \
  -d "product=${PRODUCT}" \
  -d "serial=${SERIAL}" \
  -d "signature=${SIGNATURE}"

echo
echo "Sign data was: ${SIGN_DATA}"
更多 PHP 代码请看 PHP 示例 章节,包含完整的授权管理类。