使用文档

时光授权系统文档

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

源码组成

授权系统的源码组织清晰,遵循 MVC-Lite 模式:路由 + 业务逻辑 + 视图分离。下面按目录逐一介绍。

目录结构总览

license-server/
├── index.php              # 首页(公开浏览)
├── login.php              # 用户登录页
├── auth.php               # 登录注册逻辑处理
├── user_logout.php        # 退出登录
├── buy.php                # 购买流程
├── docs.php               # 文档站(本页面)
├── admin_register.php     # 管理员注册(首注册=超级管理员)
├── install.php            # 安装脚本(用完删除)
├── patch_pay.php          # 一次性补丁脚本(用完删除)
│
├── inc/                   # 核心代码(include 目录)
│   ├── bootstrap.php      # 入口加载
│   ├── functions.php      # 公共函数(约 70 个)
│   ├── shiguang_helper.php # 审计/记住登录等辅助函数
│   ├── db.php             # 数据库配置(PDO)
│   ├── defaults.php       # 默认设置值
│   ├── layout.php         # 后台 layout(含左侧导航)
│   └── frontend_layout.php # 前台 layout(含顶部导航)
│
├── pages/                 # 后台管理页面
│   ├── dashboard.php      # 仪表盘
│   ├── products.php       # 产品管理
│   ├── licenses.php       # 授权管理
│   ├── orders.php         # 订单管理
│   ├── users.php          # 用户管理
│   ├── settings.php       # 系统设置
│   └── admins.php         # 管理员管理
│
├── user/                  # 用户中心页面
│   ├── index.php          # 用户中心首页
│   ├── licenses.php       # 我的授权
│   ├── orders.php         # 我的订单
│   └── profile.php        # 个人资料
│
├── api/                   # API 接口
│   └── verify.php         # 授权验证接口(插件调用)
│
├── docs/                  # 文档站内容
│   ├── guide/             # 入门指南章节
│   ├── arch/              # 架构章节
│   ├── integration/       # 对接开发章节
│   ├── api/               # API 参考章节
│   └── ops/               # 运维章节
│
├── assets/                # 静态资源
│   ├── css/
│   ├── js/
│   └── img/
│
└── vendor/                # 第三方库(可选)
    └── PHPMailer/         # 邮件发送库

关键文件详解

inc/db.php — 数据库配置

所有 PDO 连接、数据库表名常量都在这里定义:

<?php
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'license_server');
define('DB_USER', 'license_user');
define('DB_PASS', '...');
define('DB_CHARSET', 'utf8mb4');

define('HMAC_SALT', 'your-unique-salt');

function get_db() {
    static $pdo = null;
    if ($pdo === null) {
        $dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
        $pdo = new PDO($dsn, DB_USER, DB_PASS, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false,
        ]);
    }
    return $pdo;
}

function table($name) {
    static $prefix = 'lic_';
    return $prefix . $name;
}

关键设计:

  • 静态变量缓存 PDO 实例:整个请求周期共享一个连接,避免重复连接
  • 表前缀 lic_:方便多套系统共用一个 MySQL 实例
  • 异常模式:查询错误抛出异常,统一在 catch 中处理

inc/functions.php — 公共函数库

这里集中了系统 70+ 个核心函数,按职责可分为:

类别函数示例作用
用户认证 get_user() / attempt_login() / is_user_logged_in() 获取当前登录用户、校验凭证、判断登录态
授权验证 verify_license() / activate_license() / complete_order() 授权码校验、激活、订单完成后生成授权
支付网关 epay_create_order() / epay_verify_sign() 调用易支付、验证异步回调签名
订单管理 create_order() / complete_order() / cancel_expired_orders() 订单生命周期管理
设置管理 get_setting() / update_settings() 系统设置的读取与更新(KV 存储)
辅助函数 e() / redirect() / table() / get_db() HTML 转义、跳转、表前缀、PDO

api/verify.php — 授权验证 API

这是唯一对外暴露的验证接口,插件客户端调用此接口验证授权:

<?php
require_once '../inc/functions.php';

$input = json_decode(file_get_contents('php://input'), true)
       ?: $_POST;

// 1. 校验签名(防止伪造请求)
$signature = $input['signature'] ?? '';
$sign_str  = $input['domain'] . '|' . $input['license_key']
            . '|' . $input['product'] . '|' . ($input['serial'] ?? 1);
$expected  = hash_hmac('sha256', $sign_str, API_SECRET);

if (!hash_equals($expected, $signature)) {
    http_response_code(403);
    echo json_encode(['status' => 'error', 'message' => '签名错误']);
    exit;
}

// 2. 查询授权记录
$db = get_db();
$stmt = $db->prepare("SELECT * FROM " . table('licenses') . "
    WHERE license_key = ? AND product_slug = ? LIMIT 1");
$stmt->execute([$input['license_key'], $input['product']]);
$license = $stmt->fetch();

if (!$license) {
    echo json_encode(['status' => 'error', 'message' => '授权不存在']);
    exit;
}

// 3. 校验域名
if ($license['domain'] !== normalize_domain($input['domain'])) {
    echo json_encode(['status' => 'error', 'message' => '域名不匹配']);
    exit;
}

// 4. 校验状态
if ($license['status'] !== 'active') {
    echo json_encode(['status' => 'error', 'message' => '授权已暂停']);
    exit;
}

// 5. 校验过期
if ($license['expires_at'] && strtotime($license['expires_at']) < time()) {
    echo json_encode(['status' => 'error', 'message' => '授权已过期']);
    exit;
}

// 6. 更新 serial(首次验证返回 1,后续递增)
$serial = (int) $license['verify_count'] + 1;
$db->prepare("UPDATE " . table('licenses') . " SET verify_count = ?, last_verify_at = NOW() WHERE id = ?")
   ->execute([$serial, $license['id']]);

// 7. 返回成功
echo json_encode([
    'status' => 'success',
    'message' => '授权有效',
    'data' => [
        'serial'   => $serial,
        'license'  => [
            'key'        => $license['license_key'],
            'domain'     => $license['domain'],
            'type'       => $license['type'],
            'status'     => 'active',
            'max_sites'  => (int) $license['max_sites'],
            'expires_at' => $license['expires_at'],
        ],
        'product' => [
            'name'  => $license['product_name'],
            'slug'  => $license['product_slug'],
        ],
    ],
]);

inc/layout.php — 后台 layout

所有 pages/*.php 都通过 layout_header('页面标题') / layout_footer() 调用统一外壳,包含:

  • 顶部 Logo + 用户菜单
  • 左侧主导航(仪表盘 / 产品 / 授权 / 订单 / 用户 / 设置)
  • 右侧内容区(由各页面自行填充)
  • 底部版权

数据库 Schema

系统共使用 12 张表,按功能分组:

表名作用关键字段
lic_users 终端用户 id, username, email, password, status, created_at
lic_admins 管理员 id, username, password, role (super_admin/admin)
lic_products 产品(每个插件对应一个产品) id, name, slug, price, license_mode, product_secret
lic_licenses 授权码(用户购买后生成) id, license_key, user_id, product_id, domain, status, expires_at
lic_orders 订单 id, order_no, user_id, product_id, domain, amount, pay_status
lic_settings 系统设置(KV 存储) key, value
lic_user_logs 用户操作日志 id, user_id, action, ip, user_agent, created_at
lic_admin_audit_logs 管理员审计日志 id, admin_id, action, setting_key, old_value, new_value
lic_login_attempts 登录失败记录(防爆破) id, identifier, ip, success, attempted_at
lic_remember_tokens 记住登录 token id, user_id, token_hash, expires_at
lic_cardkeys 卡密 id, code, product_id, status, used_by, used_at
lic_announcements 公告 id, title, content, position, enabled
详细的表结构请参考 数据库设计 章节。