实现oauth2
This commit is contained in:
167
db/oauth2_schema.sql
Normal file
167
db/oauth2_schema.sql
Normal file
@@ -0,0 +1,167 @@
|
||||
-- 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 '是否要求PKCE(1=要求,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;
|
||||
Reference in New Issue
Block a user