Files
yunzerwebsiteallinone/go/docs/sql/create_auth_tables.sql
T
2026-09-19 21:44:04 +08:00

259 lines
15 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =============================================================
-- 统一认证中心(UAC)表结构 数据库:go-platform
-- 路径:api.yunzer.cn/auth
--
-- 设计要点:
-- 1. yz_auth_identity 为「自然人」层,密码上提到这一层;
-- 2. yz_auth_tenant_user 为「身份-企业」绑定,一人可在多家企业任职;
-- 3. 密码列存 PHC 格式($argon2id$...),盐内联,无需独立 salt 列;
-- 历史数据为 salt$sha256(legacy),首次登录时自动升级;
-- 4. 会话/刷新令牌/授权码均存哈希,明文不下发到数据库;
-- 5. 本脚本只建表不写数据,数据迁移由 scripts/migrate_auth.go 完成。
-- =============================================================
SET NAMES utf8mb4;
-- ---------------- 1. 统一身份(自然人) ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_identity` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '身份ID',
`union_id` VARCHAR(32) NOT NULL COMMENT '全局唯一标识(32位随机串)',
`mobile` VARCHAR(20) DEFAULT NULL COMMENT '手机号,全局唯一',
`email` VARCHAR(128) DEFAULT NULL COMMENT '邮箱,全局唯一',
`password_algo` VARCHAR(16) NOT NULL DEFAULT 'argon2id' COMMENT 'argon2id/legacy',
`password_hash` VARCHAR(255) DEFAULT NULL COMMENT 'PHC格式,含盐与参数',
`password_ver` INT NOT NULL DEFAULT 1 COMMENT '密码版本,改密时+1用于踢下线',
`nickname` VARCHAR(64) DEFAULT NULL,
`avatar` VARCHAR(500) DEFAULT NULL,
`mfa_enabled` TINYINT NOT NULL DEFAULT 0 COMMENT '是否开启二次验证',
`mfa_secret` VARCHAR(128) DEFAULT NULL COMMENT 'TOTP密钥(加密存储)',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1启用/0禁用/2锁定',
`fail_count` INT NOT NULL DEFAULT 0 COMMENT '连续失败次数',
`locked_until` DATETIME DEFAULT NULL COMMENT '锁定截止时间',
`last_login_at` DATETIME DEFAULT NULL,
`last_login_ip` VARCHAR(45) DEFAULT NULL,
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`delete_time` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_union_id` (`union_id`),
UNIQUE KEY `uk_mobile` (`mobile`),
UNIQUE KEY `uk_email` (`email`),
KEY `idx_status` (`status`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-身份表';
-- ---------------- 2. 身份-企业绑定(一人多企) ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_tenant_user` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`tid` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
`identity_id` BIGINT UNSIGNED NOT NULL COMMENT '身份ID',
`account` VARCHAR(64) DEFAULT NULL COMMENT '企业内账号,可空(用手机号登录)',
`name` VARCHAR(64) DEFAULT NULL COMMENT '在该企业的姓名',
`phone` VARCHAR(20) DEFAULT NULL,
`email` VARCHAR(128) DEFAULT NULL,
`group_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '角色ID(cid=2的租户角色)',
`org_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '部门ID',
`is_default` TINYINT NOT NULL DEFAULT 0 COMMENT '是否默认企业',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1启用/0禁用',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`delete_time` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tid_identity` (`tid`, `identity_id`),
KEY `idx_identity` (`identity_id`),
KEY `idx_tid_account` (`tid`, `account`),
KEY `idx_tid_status` (`tid`, `status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-身份企业绑定';
-- ---------------- 3. 接入应用(OIDC Client) ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_client` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`client_id` VARCHAR(64) NOT NULL,
`client_secret` VARCHAR(128) DEFAULT NULL COMMENT '机密客户端才有,存哈希',
`app_code` VARCHAR(32) NOT NULL COMMENT 'crm/oa/uniapp/website...',
`name` VARCHAR(128) NOT NULL,
`app_type` TINYINT NOT NULL DEFAULT 1 COMMENT '1Web后端 2SPA 3原生APP 4小程序',
`redirect_uris` TEXT COMMENT 'JSON数组,精确匹配白名单',
`post_logout_uris` TEXT COMMENT '登出后允许回跳的地址',
`backchannel_logout_uri` VARCHAR(500) DEFAULT NULL COMMENT '单点登出回调(服务端通知)',
`grant_types` VARCHAR(255) NOT NULL DEFAULT 'authorization_code,refresh_token',
`scope` VARCHAR(255) DEFAULT 'openid,profile,tenant',
`access_ttl` INT NOT NULL DEFAULT 1800 COMMENT '访问令牌有效期(秒)',
`refresh_ttl` INT NOT NULL DEFAULT 2592000 COMMENT '刷新令牌有效期(秒)',
`realm` VARCHAR(16) NOT NULL DEFAULT 'tenant' COMMENT 'tenant/platform',
`status` TINYINT NOT NULL DEFAULT 1,
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_client_id` (`client_id`),
UNIQUE KEY `uk_app_code` (`app_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-接入应用';
-- ---------------- 4. 登录会话(1号1机 / 强制下线) ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_session` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`sid` VARCHAR(64) NOT NULL COMMENT '会话ID,写入JWT的sid',
`identity_id` BIGINT UNSIGNED NOT NULL,
`tid` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '当前所选企业',
`client_id` VARCHAR(64) NOT NULL DEFAULT '',
`device_id` VARCHAR(64) DEFAULT NULL,
`device_name` VARCHAR(128) DEFAULT NULL,
`ip` VARCHAR(45) DEFAULT NULL,
`user_agent` VARCHAR(500) DEFAULT NULL,
`login_type` VARCHAR(20) NOT NULL DEFAULT 'password',
`amr` VARCHAR(64) DEFAULT NULL COMMENT 'pwd/sms/otp/wx/dingtalk/feishu/qq/github/google',
`login_at` DATETIME NOT NULL,
`last_access_at` DATETIME NOT NULL,
`expires_at` DATETIME NOT NULL,
`revoked` TINYINT NOT NULL DEFAULT 0,
`revoke_reason` VARCHAR(64) DEFAULT NULL COMMENT 'logout/kicked/admin/expired',
`revoke_at` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_sid` (`sid`),
KEY `idx_identity_status` (`identity_id`, `revoked`),
KEY `idx_tid` (`tid`),
KEY `idx_expires` (`expires_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-登录会话';
-- ---------------- 5. 刷新令牌(轮换 + 重放检测) ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_refresh_token` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`token_hash` VARCHAR(128) NOT NULL COMMENT '不透明串的哈希,明文不下发落库',
`identity_id` BIGINT UNSIGNED NOT NULL,
`tid` BIGINT UNSIGNED NOT NULL DEFAULT 0,
`client_id` VARCHAR(64) NOT NULL DEFAULT '',
`sid` VARCHAR(64) NOT NULL DEFAULT '',
`family_id` VARCHAR(64) NOT NULL COMMENT '轮换家族,检测到重放则整族吊销',
`rotated_from` VARCHAR(128) DEFAULT NULL,
`used` TINYINT NOT NULL DEFAULT 0,
`revoked` TINYINT NOT NULL DEFAULT 0,
`expires_at` DATETIME NOT NULL,
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_token_hash` (`token_hash`),
KEY `idx_family` (`family_id`),
KEY `idx_identity` (`identity_id`),
KEY `idx_expires` (`expires_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-刷新令牌';
-- ---------------- 6. 授权码(一次性,60秒) ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_code` (
`code_hash` VARCHAR(128) NOT NULL COMMENT '授权码哈希',
`client_id` VARCHAR(64) NOT NULL,
`identity_id` BIGINT UNSIGNED NOT NULL,
`tid` BIGINT UNSIGNED NOT NULL DEFAULT 0,
`redirect_uri` VARCHAR(500) NOT NULL,
`code_challenge` VARCHAR(128) NOT NULL COMMENT 'PKCE',
`code_challenge_method` VARCHAR(10) NOT NULL DEFAULT 'S256',
`scope` VARCHAR(255) DEFAULT NULL,
`nonce` VARCHAR(128) DEFAULT NULL COMMENT 'OIDC nonce,进ID Token',
`used` TINYINT NOT NULL DEFAULT 0,
`expires_at` DATETIME NOT NULL,
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`code_hash`),
KEY `idx_expires` (`expires_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-授权码';
-- ---------------- 7. 令牌吊销表(登出/踢下线) ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_token_blacklist` (
`jti` VARCHAR(64) NOT NULL COMMENT 'JWT ID',
`identity_id` BIGINT UNSIGNED NOT NULL DEFAULT 0,
`sid` VARCHAR(64) DEFAULT NULL,
`reason` VARCHAR(64) DEFAULT NULL,
`expires_at` DATETIME NOT NULL COMMENT '原token过期时间,到期后可清理',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`jti`),
KEY `idx_expires` (`expires_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-令牌吊销表';
-- ---------------- 8. 第三方身份绑定 ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_identity_third` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`identity_id` BIGINT UNSIGNED NOT NULL,
`provider` VARCHAR(32) NOT NULL COMMENT 'wechat/dingtalk/feishu/qq/github/google',
`open_id` VARCHAR(128) NOT NULL COMMENT '该平台内的唯一ID',
`union_id` VARCHAR(128) DEFAULT NULL COMMENT '跨平台唯一ID(微信/钉钉有)',
`nickname` VARCHAR(128) DEFAULT NULL,
`avatar` VARCHAR(500) DEFAULT NULL,
`raw` TEXT COMMENT '原始用户信息JSON',
`bind_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_provider_open` (`provider`, `open_id`),
KEY `idx_identity` (`identity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-第三方绑定';
-- ---------------- 9. 租户自带身份源(企业微信/钉钉/飞书/OIDC) ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_tenant_idp` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`tid` BIGINT UNSIGNED NOT NULL,
`provider` VARCHAR(32) NOT NULL COMMENT 'dingtalk/feishu/wework/oidc/saml',
`name` VARCHAR(128) DEFAULT NULL COMMENT '显示名称',
`app_id` VARCHAR(128) DEFAULT NULL,
`app_secret` VARCHAR(512) DEFAULT NULL COMMENT '加密存储',
`issuer` VARCHAR(500) DEFAULT NULL COMMENT 'OIDC/SAML issuer',
`auth_url` VARCHAR(500) DEFAULT NULL,
`token_url` VARCHAR(500) DEFAULT NULL,
`userinfo_url` VARCHAR(500) DEFAULT NULL,
`jwks_url` VARCHAR(500) DEFAULT NULL,
`scopes` VARCHAR(255) DEFAULT NULL,
`attr_map` TEXT COMMENT 'JSON:字段映射(手机/姓名/部门)',
`proxy_url` VARCHAR(500) DEFAULT NULL COMMENT 'GitHub/Google等需要代理时填写',
`status` TINYINT NOT NULL DEFAULT 1,
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tid_provider` (`tid`, `provider`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-租户身份源';
-- ---------------- 10. 租户登录策略 ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_tenant_auth_config` (
`tid` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
`verify_type` VARCHAR(20) NOT NULL DEFAULT 'captcha' COMMENT 'none/captcha/sms/email/geetest',
`open_verify` TINYINT NOT NULL DEFAULT 1 COMMENT '是否开启登录二次验证',
`pwd_min_len` INT NOT NULL DEFAULT 8,
`pwd_complexity` TINYINT NOT NULL DEFAULT 0 COMMENT '0不限制 1字母+数字 2大小写+数字+符号',
`session_ttl` INT NOT NULL DEFAULT 7200 COMMENT '会话有效期(秒)',
`max_session` INT NOT NULL DEFAULT 1 COMMENT '同账号最大同时在线数(默认1号1机)',
`kick_strategy` TINYINT NOT NULL DEFAULT 1 COMMENT '1踢掉旧会话 2拒绝新登录',
`mfa_required` TINYINT NOT NULL DEFAULT 0,
`ip_whitelist` TEXT COMMENT 'JSON数组,为空表示不限制',
`allow_third` VARCHAR(255) DEFAULT NULL COMMENT '允许的第三方登录,逗号分隔,空表示全部',
`update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-租户登录策略';
-- ---------------- 11. 统一登录日志 ----------------
CREATE TABLE IF NOT EXISTS `yz_auth_login_log` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`tid` BIGINT UNSIGNED DEFAULT NULL,
`identity_id` BIGINT UNSIGNED DEFAULT NULL,
`account` VARCHAR(64) NOT NULL DEFAULT '',
`user_name` VARCHAR(64) NOT NULL DEFAULT '',
`tenant_name` VARCHAR(64) NOT NULL DEFAULT '',
`client_id` VARCHAR(64) NOT NULL DEFAULT '',
`login_type` VARCHAR(20) NOT NULL DEFAULT 'password' COMMENT 'password/sms/otp/third',
`amr` VARCHAR(64) DEFAULT NULL,
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1成功/0失败',
`message` VARCHAR(255) NOT NULL DEFAULT '',
`ip` VARCHAR(45) NOT NULL DEFAULT '',
`user_agent` VARCHAR(500) NOT NULL DEFAULT '',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_tid` (`tid`),
KEY `idx_identity` (`identity_id`),
KEY `idx_account` (`account`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一认证-登录日志';
-- =============================================================
-- 内置接入应用(后续由 platform 端「应用注册」页面维护)
-- client_secret 为占位值,正式启用前必须在管理端重新生成
-- =============================================================
INSERT INTO `yz_auth_client`
(`client_id`, `app_code`, `name`, `app_type`, `grant_types`, `scope`, `access_ttl`, `refresh_ttl`, `realm`)
VALUES
('yz-backend', 'backend', '租户管理后台', 2, 'authorization_code,refresh_token', 'openid,profile,tenant', 1800, 2592000, 'tenant'),
('yz-uniapp', 'uniapp', '移动端APP', 3, 'authorization_code,refresh_token', 'openid,profile,tenant', 1800, 2592000, 'tenant'),
('yz-website', 'website', '企业官网', 2, 'authorization_code,refresh_token', 'openid,profile,tenant', 1800, 2592000, 'tenant')
ON DUPLICATE KEY UPDATE `name` = VALUES(`name`);