使用文档

时光授权系统文档

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

数据库设计

授权系统共 12 张表,按功能分为:用户表、管理员表、产品表、授权表、订单表、设置表、日志表、辅助表。所有表统一前缀 lic_。

ER 关系图

┌─────────────┐       ┌─────────────┐       ┌─────────────┐
│ lic_users   │──┐    │ lic_products │──┐    │ lic_orders   │
│ (终端用户)   │  │    │  (产品)      │  │    │  (订单)      │
└─────────────┘  │    └─────────────┘  │    └─────────────┘
                 │           │          │           │
                 │ 1:N       │ 1:N      │ N:1       │
                 ▼           ▼          │           │
            ┌─────────────────────────┐ │           │
            │   lic_licenses          │◀┘           │
            │   (授权码)               │───────────────┘
            └─────────────────────────┘  1:1 (license_id)
                 │           │
                 │           │ N:1
                 │           ▼
                 │    ┌─────────────┐
                 │    │ lic_products│
                 │    └─────────────┘
                 │
                 │ N:1
                 ▼
            ┌─────────────┐
            │ lic_users   │
            └─────────────┘

核心表结构

lic_users — 终端用户表

CREATE TABLE lic_users (
    id              INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    username        VARCHAR(50)  NOT NULL,
    email           VARCHAR(100) NOT NULL,
    password        VARCHAR(255) NOT NULL,        -- password_hash 加密
    phone           VARCHAR(20)  DEFAULT NULL,
    status          ENUM('active', 'banned') DEFAULT 'active',
    last_login_at   DATETIME     DEFAULT NULL,
    last_login_ip   VARCHAR(45)  DEFAULT '',
    created_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY uk_username (username),
    UNIQUE KEY uk_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

关键设计:

  • 用户名、邮箱都加唯一索引
  • 密码用 password_hash($password, PASSWORD_BCRYPT) 存储,永远不存明文
  • last_login_at 用于显示"上次登录时间"和异常检测

lic_products — 产品表

CREATE TABLE lic_products (
    id              INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name            VARCHAR(100) NOT NULL,        -- "夸克网盘二维码插件"
    slug            VARCHAR(50)  NOT NULL,        -- "shiguang-quark-qrcode"
    description     TEXT         DEFAULT NULL,    -- 简介
    detail_md       MEDIUMTEXT   DEFAULT NULL,    -- 详细介绍(Markdown)
    price           DECIMAL(10,2) DEFAULT 0.00,  -- 0=免费
    validity_days   INT          DEFAULT 0,       -- 0=永久
    max_sites       INT          DEFAULT 1,       -- 授权站点数
    license_mode    ENUM('system','custom') DEFAULT 'system',
    product_secret  VARCHAR(64)  DEFAULT '',     -- 32 字符 API 签名密钥
    status          TINYINT(1)   DEFAULT 1,       -- 1=上架 0=下架
    sort_order      INT          DEFAULT 0,
    created_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    updated_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_slug (slug)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

slug 是关键字段:插件代码里硬编码这个值,授权验证时传给 API。所以改 slug 等于发布新产品,要谨慎。

lic_licenses — 授权码表

CREATE TABLE lic_licenses (
    id              INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    license_key     VARCHAR(32) NOT NULL,          -- LIC-XXXXX-XXXXX-XXXXX-XXXXX
    user_id         INT UNSIGNED NOT NULL,
    product_id      INT UNSIGNED NOT NULL,
    domain          VARCHAR(255) DEFAULT '',       -- 标准化后的域名
    status          ENUM('active','suspended','expired') DEFAULT 'active',
    type            VARCHAR(20) DEFAULT 'standard', -- standard/pro/trial
    expires_at      DATETIME DEFAULT NULL,          -- null=永久
    max_sites       INT DEFAULT 1,
    verify_count    INT UNSIGNED DEFAULT 0,         -- 累计验证次数
    last_verify_at  DATETIME DEFAULT NULL,
    last_verify_ip  VARCHAR(45) DEFAULT '',
    created_at      TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY uk_license_key (license_key),
    UNIQUE KEY uniq_user_product_domain (user_id, product_id, domain),
    INDEX idx_user (user_id),
    INDEX idx_product (product_id),
    INDEX idx_status (status),
    INDEX idx_expires (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

关键索引:

  • uk_license_key:授权码全局唯一(避免重复)
  • uniq_user_product_domain:防止同一用户重复购买同一产品的同一域名(数据库级约束)
  • idx_status + idx_expires:加速过期清理任务

lic_orders — 订单表

CREATE TABLE lic_orders (
    id              INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    order_no        VARCHAR(32) NOT NULL,          -- 业务订单号
    user_id         INT UNSIGNED NOT NULL,
    product_id      INT UNSIGNED NOT NULL,
    domain          VARCHAR(255) NOT NULL,         -- 用户购买时填的域名
    amount          DECIMAL(10,2) DEFAULT 0.00,
    pay_type        ENUM('alipay','wechat','wxpay','qqpay') DEFAULT 'alipay',
    pay_status      ENUM('pending','paid','completed','failed','refunded') DEFAULT 'pending',
    pay_trade_no    VARCHAR(64) DEFAULT '',        -- 支付网关返回的交易号
    license_id      INT UNSIGNED DEFAULT NULL,     -- 关联的授权码
    mode            ENUM('new','renew') DEFAULT 'new',
    created_at      TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    paid_at         DATETIME DEFAULT NULL,
    completed_at    DATETIME DEFAULT NULL,
    expired_at      DATETIME DEFAULT NULL,         -- 订单超时时间
    UNIQUE KEY uk_order_no (order_no),
    INDEX idx_user (user_id),
    INDEX idx_product (product_id),
    INDEX idx_pay_status (pay_status),
    INDEX idx_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

lic_settings — 系统设置

采用 KV 存储,所有动态配置都在这里:

CREATE TABLE lic_settings (
    id          INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `key`       VARCHAR(100) NOT NULL,
    value       TEXT DEFAULT NULL,
    updated_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_key (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

常用 key 示例:

key说明默认值
site_name站点名称License Server
site_logo站点 Logo URL—
epay_url易支付网关空
epay_pid易支付商户 ID空
epay_key易支付商户密钥空
epay1_pay_type第一通道支付类型(alipay/wechat/none)alipay
epay2_enabled是否启用第二通道0
epay2_pay_type第二通道支付类型wechat
order_timeout_minutes订单超时时间(分钟)30
remember_login_days记住登录有效期(天)7

lic_remember_tokens — 记住登录

CREATE TABLE lic_remember_tokens (
    id              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    user_id         INT UNSIGNED NOT NULL,
    token_hash      CHAR(64) NOT NULL,            -- SHA256(token)
    expires_at      DATETIME NOT NULL,
    created_ip      VARCHAR(45) DEFAULT '',
    last_used_at    DATETIME DEFAULT NULL,
    INDEX idx_user (user_id),
    INDEX idx_hash (token_hash),
    INDEX idx_expires (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

关键:只存哈希,不存明文 token。即使数据库泄露,攻击者也无法伪造 cookie。

性能优化

  • 覆盖索引:idx_user_product 可加速查询某用户某产品的所有授权
  • 分区表:订单表/日志表可按时间分区(订单数据量大时建议)
  • 慢查询监控:定期 EXPLAIN 检查大表查询

数据迁移

新版本发布时,可能涉及表结构变更。建议:

  1. 在 install.php 中用 CREATE TABLE IF NOT EXISTS 兼容旧库
  2. 用 ALTER TABLE + 条件判断实现"幂等迁移"
  3. 迁移前务必备份数据库
<?php
// 幂等迁移示例
$db->exec("CREATE TABLE IF NOT EXISTS lic_new_table (
    id INT PRIMARY KEY AUTO_INCREMENT,
    ...
) ENGINE=InnoDB");

// 检查列是否存在再添加
$columns = $db->query("SHOW COLUMNS FROM lic_users")->fetchAll(PDO::FETCH_COLUMN);
if (!in_array('phone', $columns)) {
    $db->exec("ALTER TABLE lic_users ADD COLUMN phone VARCHAR(20) DEFAULT NULL AFTER email");
}