-- SSO单点登录表结构 -- 创建SSO令牌表 CREATE TABLE IF NOT EXISTS sso_token ( id BIGSERIAL PRIMARY KEY, user_id VARCHAR(50) NOT NULL, username VARCHAR(100) NOT NULL, token VARCHAR(500) NOT NULL, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, expire_time TIMESTAMP NOT NULL, status INTEGER DEFAULT 1, last_use_time TIMESTAMP, INDEX idx_token (token), INDEX idx_user_id (user_id), INDEX idx_expire_time (expire_time) ); -- 创建应用注册表 CREATE TABLE IF NOT EXISTS app_registry ( id BIGSERIAL PRIMARY KEY, app_name VARCHAR(100) NOT NULL UNIQUE, app_key VARCHAR(200) NOT NULL UNIQUE, app_secret VARCHAR(500) NOT NULL, redirect_uri VARCHAR(500) NOT NULL, description TEXT, status INTEGER DEFAULT 1, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, admin_user VARCHAR(100), INDEX idx_app_key (app_key), INDEX idx_status (status) ); -- 创建SSO访问日志表 CREATE TABLE IF NOT EXISTS sso_access_log ( id BIGSERIAL PRIMARY KEY, user_id VARCHAR(50), username VARCHAR(100), app_name VARCHAR(100), action VARCHAR(50) NOT NULL, -- login, logout, validate, token_exchange ip_address VARCHAR(50), user_agent TEXT, token_used VARCHAR(500), status INTEGER DEFAULT 1, -- 1:成功, 0:失败 error_message TEXT, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_user_id (user_id), INDEX idx_username (username), INDEX idx_app_name (app_name), INDEX idx_create_time (create_time) ); -- 创建应用接入记录表 CREATE TABLE IF NOT EXISTS app_access_log ( id BIGSERIAL PRIMARY KEY, app_key VARCHAR(200) NOT NULL, app_name VARCHAR(100) NOT NULL, client_id VARCHAR(200), action VARCHAR(50) NOT NULL, -- register, validate, auth, token_request ip_address VARCHAR(50), user_agent TEXT, request_data TEXT, response_data TEXT, status INTEGER DEFAULT 1, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_app_key (app_key), INDEX idx_create_time (create_time) ); -- 创建权限配置表 CREATE TABLE IF NOT EXISTS app_permission ( id BIGSERIAL PRIMARY KEY, app_key VARCHAR(200) NOT NULL, permission_name VARCHAR(100) NOT NULL, permission_code VARCHAR(200) NOT NULL, resource_type VARCHAR(50), -- api, menu, button resource_id VARCHAR(200), is_enabled INTEGER DEFAULT 1, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_app_key_permission (app_key, permission_code), INDEX idx_app_key (app_key), INDEX idx_permission_code (permission_code) ); -- 创建Token刷新记录表 CREATE TABLE IF NOT EXISTS refresh_token ( id BIGSERIAL PRIMARY KEY, user_id VARCHAR(50) NOT NULL, username VARCHAR(100) NOT NULL, access_token VARCHAR(500) NOT NULL, refresh_token VARCHAR(500) NOT NULL, client_id VARCHAR(200) NOT NULL, scope VARCHAR(500), create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, expire_time TIMESTAMP NOT NULL, last_use_time TIMESTAMP, is_revoked INTEGER DEFAULT 0, INDEX idx_access_token (access_token), INDEX idx_refresh_token (refresh_token), INDEX idx_user_id (user_id), INDEX idx_client_id (client_id) ); -- 插入默认的OAuth2客户端配置 INSERT INTO app_registry (app_name, app_key, app_secret, redirect_uri, description, admin_user) VALUES ('营收管理前端', 'revenue-frontend', 'revenue-frontend-secret-2026', 'http://localhost:3000/oauth/callback', '营收管理平台前端应用', 'admin'), ('微信网厅', 'wechat-mall', 'wechat-mall-secret-2026', 'http://localhost:8080/wechat/callback', '微信网上营业厅应用', 'admin'), ('移动端应用', 'mobile-app', 'mobile-app-secret-2026', 'http://localhost:4000/auth/callback', '移动端应用', 'admin') ON CONFLICT (app_name) DO NOTHING; -- 创建SSO触发器:自动清理过期Token CREATE OR REPLACE FUNCTION clean_expired_tokens() RETURNS TRIGGER AS $$ BEGIN DELETE FROM sso_token WHERE expire_time < NOW(); DELETE FROM refresh_token WHERE expire_time < NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- 创建SSO触发器:当插入token时更新最后使用时间 CREATE OR REPLACE FUNCTION update_last_use_time() RETURNS TRIGGER AS $$ BEGIN IF NEW.status = 1 THEN UPDATE sso_token SET last_use_time = NOW() WHERE token = NEW.token AND id != NEW.id; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; -- 创建触发器 CREATE TRIGGER trigger_clean_expired_tokens BEFORE INSERT OR UPDATE OR DELETE ON sso_token EXECUTE FUNCTION clean_expired_tokens(); CREATE TRIGGER trigger_update_last_use_time AFTER UPDATE ON sso_token FOR EACH ROW EXECUTE FUNCTION update_last_use_time();