Files
AI_OJ/db/oauth2_schema.sql
2025-12-14 17:47:08 +08:00

168 lines
6.1 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.
-- OAuth2/OIDC 单点登录 数据库表结构
-- 创建时间: 2025-12-14
-- =============================================
-- OAuth2 客户端表
-- =============================================
CREATE TABLE IF NOT EXISTS `oauth2_client` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`client_id` VARCHAR(100) NOT NULL COMMENT '客户端ID',
`client_secret` VARCHAR(255) NULL COMMENT '客户端密钥BCrypt加密公共客户端为NULL',
`client_name` VARCHAR(100) NOT NULL COMMENT '客户端名称',
`client_type` VARCHAR(20) NOT NULL COMMENT '客户端类型confidential机密/ public公共',
`redirect_uris` TEXT NOT NULL COMMENT '重定向URI列表JSON数组格式',
`post_logout_redirect_uris` TEXT COMMENT '登出后重定向URI列表JSON数组格式',
`allowed_scopes` VARCHAR(500) NOT NULL COMMENT '允许的作用域逗号分隔openid,profile,email',
`allowed_grant_types` VARCHAR(200) NOT NULL COMMENT '允许的授权类型逗号分隔authorization_code,refresh_token',
`access_token_ttl` INT DEFAULT 900 COMMENT 'Access Token有效期默认15分钟',
`refresh_token_ttl` INT DEFAULT 604800 COMMENT 'Refresh Token有效期默认7天',
`require_pkce` TINYINT(1) DEFAULT 1 COMMENT '是否要求PKCE1=要求0=不要求)',
`is_enabled` TINYINT(1) DEFAULT 1 COMMENT '是否启用1=启用0=禁用)',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_client_id` (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='OAuth2客户端表';
-- =============================================
-- 插入测试客户端数据
-- =============================================
-- 1. Web 应用(机密客户端)
-- client_secret 明文: web_app_secret_2024
-- BCrypt 加密后: $2a$10$XQw.gH7qKvYJ8pqXk7YRNe8xZYKZJ.3kZQH5.3zV4YXjQH5.3zV4Y
INSERT INTO `oauth2_client`
(`client_id`, `client_secret`, `client_name`, `client_type`,
`redirect_uris`, `post_logout_redirect_uris`,
`allowed_scopes`, `allowed_grant_types`,
`access_token_ttl`, `refresh_token_ttl`, `require_pkce`, `is_enabled`)
VALUES
('web-app',
'$2a$10$XQw.gH7qKvYJ8pqXk7YRNe8xZYKZJ.3kZQH5.3zV4YXjQH5.3zV4Y',
'Web应用',
'confidential',
'["http://localhost:3000/callback","http://localhost:3000/silent-renew","http://localhost:8080/callback"]',
'["http://localhost:3000/logout-callback","http://localhost:8080/logout"]',
'openid,profile,email',
'authorization_code,refresh_token',
900,
604800,
1,
1);
-- 2. 移动应用(公共客户端)
INSERT INTO `oauth2_client`
(`client_id`, `client_secret`, `client_name`, `client_type`,
`redirect_uris`, `post_logout_redirect_uris`,
`allowed_scopes`, `allowed_grant_types`,
`access_token_ttl`, `refresh_token_ttl`, `require_pkce`, `is_enabled`)
VALUES
('mobile-app',
NULL,
'移动应用',
'public',
'["acgoj://callback","acgoj://oauth/callback"]',
'["acgoj://logout","acgoj://oauth/logout"]',
'openid,profile',
'authorization_code,refresh_token',
900,
2592000, -- 30天
1, -- 强制要求PKCE
1);
-- 3. 管理后台(机密客户端)
-- client_secret 明文: admin_secret_2024
-- BCrypt 加密后: $2a$10$YRx.hI8rLwZK9qrYl8ZSOe9yAZLAK.4lARG6.4aW5ZYkRG6.4aW5A
INSERT INTO `oauth2_client`
(`client_id`, `client_secret`, `client_name`, `client_type`,
`redirect_uris`, `post_logout_redirect_uris`,
`allowed_scopes`, `allowed_grant_types`,
`access_token_ttl`, `refresh_token_ttl`, `require_pkce`, `is_enabled`)
VALUES
('admin-app',
'$2a$10$YRx.hI8rLwZK9qrYl8ZSOe9yAZLAK.4lARG6.4aW5ZYkRG6.4aW5A',
'管理后台',
'confidential',
'["http://localhost:3001/admin/callback","http://admin.acgoj.com/callback"]',
'["http://localhost:3001/admin/logout","http://admin.acgoj.com/logout"]',
'openid,profile,email,admin',
'authorization_code,refresh_token',
900,
604800,
1,
1);
-- =============================================
-- Redis 数据结构说明仅供参考Redis中存储
-- =============================================
-- 1. 授权码存储
-- Key: oauth2:auth_code:{code}
-- Value: JSON {
-- "code": "授权码",
-- "clientId": "客户端ID",
-- "userId": "用户ID",
-- "redirectUri": "重定向URI",
-- "scope": "授权范围",
-- "codeChallenge": "PKCE challenge",
-- "codeChallengeMethod": "S256",
-- "nonce": "防重放参数",
-- "expiresAt": 时间戳
-- }
-- TTL: 600秒10分钟
-- 2. 用户会话存储
-- Key: oauth2:session:{sessionId}
-- Value: JSON {
-- "sessionId": "会话ID",
-- "userId": "用户ID",
-- "clients": [
-- {
-- "clientId": "客户端ID",
-- "accessToken": "访问令牌",
-- "refreshToken": "刷新令牌",
-- "issuedAt": 时间戳
-- }
-- ],
-- "createdAt": 时间戳
-- }
-- TTL: 604800秒7天
-- 3. 用户会话索引
-- Key: oauth2:user_sessions:{userId}
-- Value: Set<sessionId>
-- TTL: 604800秒7天
-- 4. Token黑名单用于单点登出
-- Key: oauth2:token_blacklist:{SHA256(token)}
-- Value: "1"
-- TTL: Token的剩余有效期动态计算
-- 5. Refresh Token存储现有
-- Key: refresh_token:{userId}
-- Value: refresh_token字符串
-- TTL: 604800秒7天
-- =============================================
-- 索引说明
-- =============================================
-- 1. uk_client_id: 唯一索引确保client_id不重复
-- 2. 如需按client_name查询可添加: KEY `idx_client_name` (`client_name`)
-- 3. 如需按is_enabled查询可添加: KEY `idx_is_enabled` (`is_enabled`)
-- =============================================
-- 查询示例
-- =============================================
-- 查询所有启用的客户端
-- SELECT * FROM oauth2_client WHERE is_enabled = 1;
-- 根据client_id查询客户端
-- SELECT * FROM oauth2_client WHERE client_id = 'web-app';
-- 查询所有公共客户端
-- SELECT * FROM oauth2_client WHERE client_type = 'public';
-- 查询所有需要PKCE的客户端
-- SELECT * FROM oauth2_client WHERE require_pkce = 1;