feat: 增强版验证码全套实现 — 16种类型生成器/加密/风控/站点管理/平台后端/前端SDK/UI

- 核心新增: ICON_CLICK(PNG图标方案,预渲染资源)/SCRATCH/JIGSAW/CURVE_SLIDER(V1-V3)/ANGLE/CURVE_DRAW/WORD_ORDER_CLICK/PROOF_OF_WORK 等生成器
- 图标点选: classpath PNG 加载替代运行时字体渲染(Linux容器无emoji字体),提示条图作为 templateImage 返回前端
- 新增模块: crypto(AES+RSA)/obfuscator(背景乱序/噪声/扭曲)/risk(风控/IP黑名单/限流)/site(站点管理)/ml(轨迹规则引擎)
- 平台后端: 站点管理/验证码API(generate/verify/secondary-verify)/统计/ML轨迹学习
- 前端SDK: TPCaptcha兼容,支持全部新型号渲染与交互
- 工具: tools/icon-render 图标预渲染工具
This commit is contained in:
abcv7
2026-08-26 09:58:15 +08:00
parent d56958727c
commit dbe9b58b0c
115 changed files with 10365 additions and 36 deletions
@@ -0,0 +1,36 @@
server:
port: 18200
spring:
datasource:
url: jdbc:postgresql://localhost:5432/captcha_forge
username: postgres
password: XGYnJPysCNJsLeea
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: none
show-sql: false
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
sql:
init:
mode: always
data:
redis:
host: localhost
port: 6379
captcha:
prefix: captcha
expire:
default: 120000
init-default-resource: true
local-cache-enabled: true
local-cache-size: 20
logging:
level:
cloud.tianai.captcha: INFO
@@ -0,0 +1,233 @@
DROP TABLE IF EXISTS verification_logs CASCADE;
DROP TABLE IF EXISTS track_samples CASCADE;
DROP TABLE IF EXISTS captcha_challenges CASCADE;
DROP TABLE IF EXISTS captcha_categories CASCADE;
DROP TABLE IF EXISTS sites CASCADE;
DROP TABLE IF EXISTS plans CASCADE;
DROP TABLE IF EXISTS users CASCADE;
DROP TABLE IF EXISTS announcements CASCADE;
DROP TABLE IF EXISTS captcha_ip_blacklist CASCADE;
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(64) NOT NULL UNIQUE,
email VARCHAR(128),
password VARCHAR(256) NOT NULL,
role VARCHAR(16) DEFAULT 'USER',
site_amount INT DEFAULT 0,
is_enabled BOOLEAN DEFAULT TRUE,
is_system BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE plans (
id SERIAL PRIMARY KEY,
name VARCHAR(64) NOT NULL,
description VARCHAR(256),
qps INT DEFAULT 10,
daily_limit INT DEFAULT 500,
captcha_types TEXT[] DEFAULT '{SLIDER,PUZZLE,TEXT_CLICK,ICON_CLICK,ICON_UNDERSTAND}',
custom_style BOOLEAN DEFAULT FALSE,
is_enabled BOOLEAN DEFAULT TRUE,
is_system BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE sites (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(id),
name VARCHAR(64) NOT NULL,
domain VARCHAR(256),
favicon VARCHAR(512),
logo VARCHAR(512),
site_key UUID DEFAULT gen_random_uuid() UNIQUE,
secret_key UUID DEFAULT gen_random_uuid() UNIQUE,
verify_level VARCHAR(16) DEFAULT 'MEDIUM',
qps INT DEFAULT 10,
daily_limit INT DEFAULT 500,
captcha_types TEXT[] DEFAULT '{SLIDER,PUZZLE,TEXT_CLICK,ICON_CLICK,ICON_UNDERSTAND}',
plan_id INT REFERENCES plans(id),
plan_expire_at TIMESTAMPTZ,
is_enabled BOOLEAN DEFAULT TRUE,
rsa_public_key TEXT,
rsa_private_key TEXT,
aes_key VARCHAR(256),
signing_key VARCHAR(256),
track_validation_enabled BOOLEAN DEFAULT TRUE,
track_human_threshold FLOAT DEFAULT 0.5,
obfuscation_enabled BOOLEAN DEFAULT TRUE,
encryption_enabled BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE captcha_categories (
id SERIAL PRIMARY KEY,
name VARCHAR(64) NOT NULL,
label VARCHAR(64) NOT NULL,
items TEXT[] NOT NULL DEFAULT '{}',
is_enabled BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE captcha_challenges (
id SERIAL PRIMARY KEY,
category_id INT REFERENCES captcha_categories(id) ON DELETE CASCADE,
prompt TEXT NOT NULL,
correct_items TEXT[] NOT NULL DEFAULT '{}',
difficulty VARCHAR(16) DEFAULT 'MEDIUM',
is_enabled BOOLEAN DEFAULT TRUE,
use_count INT DEFAULT 0,
success_rate DOUBLE PRECISION DEFAULT 0.5,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE verification_logs (
id SERIAL PRIMARY KEY,
site_id INT REFERENCES sites(id),
site_key UUID,
captcha_type VARCHAR(32),
scene VARCHAR(64) DEFAULT 'default',
ip VARCHAR(45),
is_pass BOOLEAN,
behavior_score DOUBLE PRECISION,
risk_level VARCHAR(16),
cost_time INT,
captcha_id VARCHAR(128),
user_agent TEXT,
track_score FLOAT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE track_samples (
id SERIAL PRIMARY KEY,
site_id INT REFERENCES sites(id),
captcha_type VARCHAR(32),
is_human BOOLEAN,
ml_score DOUBLE PRECISION,
basic_pass BOOLEAN,
total_points INT,
total_duration BIGINT,
displacement_x FLOAT,
displacement_y FLOAT,
displacement_x_ratio FLOAT,
total_path_length DOUBLE PRECISION,
path_efficiency DOUBLE PRECISION,
avg_speed FLOAT,
max_speed FLOAT,
min_speed FLOAT,
speed_variance DOUBLE PRECISION,
speed_std_dev DOUBLE PRECISION,
speed_skewness DOUBLE PRECISION,
avg_acceleration FLOAT,
max_acceleration FLOAT,
min_acceleration FLOAT,
acceleration_variance DOUBLE PRECISION,
direction_changes INT,
y_direction_changes INT,
pauses INT,
start_offset DOUBLE PRECISION,
straightness DOUBLE PRECISION,
x_uniformity DOUBLE PRECISION,
y_uniformity DOUBLE PRECISION,
avg_point_interval FLOAT,
speed_phase_correlation DOUBLE PRECISION,
max_jump_distance DOUBLE PRECISION,
overshoot_ratio DOUBLE PRECISION,
track_json TEXT,
ip VARCHAR(45),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE announcements (
id SERIAL PRIMARY KEY,
title VARCHAR(256) NOT NULL,
content TEXT,
is_pinned BOOLEAN DEFAULT FALSE,
is_published BOOLEAN DEFAULT TRUE,
sort_order INT DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE captcha_ip_blacklist (
id SERIAL PRIMARY KEY,
ip VARCHAR(64) NOT NULL,
reason VARCHAR(256),
ban_until TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_sites_key ON sites(site_key);
CREATE INDEX idx_sites_user ON sites(user_id);
CREATE INDEX idx_challenges_category ON captcha_challenges(category_id);
CREATE INDEX idx_challenges_difficulty ON captcha_challenges(difficulty);
CREATE INDEX idx_logs_site ON verification_logs(site_id);
CREATE INDEX idx_logs_time ON verification_logs(created_at);
CREATE INDEX idx_logs_type ON verification_logs(captcha_type);
CREATE INDEX idx_logs_pass ON verification_logs(is_pass);
CREATE INDEX idx_ip_blacklist_ip ON captcha_ip_blacklist(ip);
CREATE INDEX idx_track_human ON track_samples(is_human);
CREATE INDEX idx_track_type ON track_samples(captcha_type);
CREATE INDEX idx_track_time ON track_samples(created_at);
CREATE INDEX idx_track_score ON track_samples(ml_score);
INSERT INTO users (username, email, password, role, site_amount, is_enabled, is_system)
VALUES ('admin', 'admin@captchaforge.local', '$2a$10$85QOiy3qD5KPuxyrrN/LcuZe3ty/OrTk6yEKAJEGtJKk97ukw2yPG', 'ADMIN', 999, TRUE, TRUE);
INSERT INTO plans (name, description, qps, daily_limit, is_enabled, is_system) VALUES
('免费套餐', '默认免费套餐', 5, 500, TRUE, TRUE),
('基础套餐', '适合中小站点', 20, 5000, TRUE, TRUE),
('专业套餐', '适合大型站点', 100, 50000, TRUE, TRUE);
INSERT INTO captcha_categories (name, label, items) VALUES
('animals', '动物', '{"🐶","🐱","🐭","🐹","🐰","🦊","🐻","🐼","🐨","🐯","🦁","🐮","🐷","🐸","🐵","🐔","🐧","🐦","🦅","🦆","🦉","🐴","🦄","🐝","🐛","🦋","🐌","🐞","🐢","🐍","🦎","🐙","🦑","🦐","🦀","🐠","🐟","🐬","🐳","🐊","🐘","🦏","🐪","🦒","🐕","🐈","🐓","🦃","🦚","🦜","🐇","🦔","🐺","🐗"}'),
('food', '食物饮品', '{"🍎","🍐","🍊","🍋","🍌","🍉","🍇","🍓","🍒","🍑","🥭","🍍","🥥","🥝","🍅","🍆","🥑","🥦","🌽","🥕","🍞","🧀","🍳","🍔","🍟","🍕","🌮","🍣","🍜","🍩","🍪","🎂","🍫","🍭","☕","🍵","🧃","🥤","🍺","🍷"}'),
('vehicles', '交通工具', '{"🚗","🚕","🚙","🚌","🏎","🚓","🚑","🚒","🚐","🚚","🚛","🚜","🚲","🛵","🏍","🚨","🚔","🚡","🚠","🚃","🚋","🚄","🚅","🚂","✈️","🛩","🚀","🛸","🚁","⛵","🚤","🛳","⛴","🚢"}'),
('nature', '天气自然', '{"☀️","🌤","⛅","🌥","☁️","🌦","🌧","⛈","🌩","🌨","❄️","☃️","🌪","🌈","🌊","💧","🔥","⭐","🌟","✨","⚡","☄️","🌸","🌺","🌻","🌹","🌷","🌱","🌿","🍀","🍁","🍂","🍃","🌴","🌵"}'),
('sports', '运动娱乐', '{"⚽","🏀","🏈","⚾","🎾","🏐","🏉","🎱","🏓","🏸","🏒","🏑","🥍","🎯","🎳","🎮","🎲","♟","🧩","🪀","🪁","🎪","🤹","🎭","🎨","🎬","🎤","🎧","🎹","🥁","🎸","🎻"}'),
('buildings', '建筑地点', '{"🏠","🏡","🏢","🏣","🏤","🏥","🏦","🏨","🏩","🏪","🏫","🏬","🏭","🏯","🏰","💒","🗼","🗽","⛪","🕌","🛕","🕍","⛩","🕋","⛲","⛺","🏕"}'),
('objects', '电子物品', '{"⌚","📱","💻","⌨️","🖥","🖨","🖱","🖲","💾","💿","📷","📹","🎥","📞","📺","📻","🔋","🔌","💡","🔦","🕯","🔑","🔒","🔓","📧","📮","📦","📋","📁","✏️","🖊","🖋","✒️","🖌","📝","🔍","📎","📐","📌","✂️","🧲","🔧","🔨","⚙️","💊","💉","🩺","🧬","🔭","🔬","🧪"}'),
('gestures', '手势动作', '{"👋","🤚","🖐","✋","🖖","👌","🤌","🤏","✌","🤞","🤟","🤘","🤙","👈","👉","👆","👇","☝️","👍","👎","✊","👊","🤛","🤜","👏","🙌","👐","🤲","🤝","🙏","✍️","💅","🤳","💪"}');
INSERT INTO captcha_challenges (category_id, prompt, correct_items, difficulty) VALUES
(1, '请点击所有的猫科动物', '{"🐱","🐯","🦁","🐈"}', 'MEDIUM'),
(1, '请点击所有的犬科动物', '{"🐶","🐺","🐕"}', 'MEDIUM'),
(1, '请点击所有的鸟类', '{"🐔","🐧","🐦","🦅","🦆","🦉","🦜","🦚","🦃"}', 'MEDIUM'),
(1, '请点击所有的水生动物', '{"🐙","🦑","🦐","🦀","🐠","🐟","🐬","🐳"}', 'MEDIUM'),
(1, '请点击所有的昆虫', '{"🐝","🐛","🦋","🐌","🐞","🦟"}', 'MEDIUM'),
(2, '请点击所有的水果', '{"🍎","🍐","🍊","🍋","🍌","🍉","🍇","🍓","🍒","🍑","🥭","🍍","🥝"}', 'MEDIUM'),
(2, '请点击所有的蔬菜', '{"🍅","🍆","🥑","🥦","🌽","🥕"}', 'MEDIUM'),
(2, '请点击所有的饮品', '{"☕","🍵","🧃","🥤","🍺","🍷"}', 'MEDIUM'),
(2, '请点击所有的甜点', '{"🍩","🍪","🎂","🍫","🍭"}', 'MEDIUM'),
(3, '请点击所有的汽车', '{"🚗","🚕","🚙","🏎","🚓","🚑","🚒","🚐"}', 'MEDIUM'),
(3, '请点击所有的飞行器', '{"✈️","🛩","🚀","🛸","🚁"}', 'MEDIUM'),
(3, '请点击所有的船只', '{"⛵","🚤","🛳","⛴","🚢"}', 'MEDIUM'),
(4, '请点击所有与降水相关的', '{"🌦","🌧","⛈","🌩","🌨"}', 'MEDIUM'),
(4, '请点击所有的花卉', '{"🌸","🌺","🌻","🌹","🌷"}', 'MEDIUM'),
(4, '请点击所有的天体', '{"☀️","⭐","🌟","✨","⚡","☄️"}', 'MEDIUM'),
(5, '请点击所有的球类运动', '{"⚽","🏀","🏈","⚾","🎾","🏐","🏉"}', 'MEDIUM'),
(5, '请点击所有的音乐相关', '{"🎤","🎧","🎹","🥁","🎸","🎻"}', 'MEDIUM'),
(5, '请点击所有的棋牌游戏', '{"🎲","♟","🧩","🎮","🎯","🎱"}', 'MEDIUM'),
(1, '请点击所有的动物', '{"🐶","🐱","🐭","🐹","🐰","🦊","🐻","🐼","🐨","🐯","🦁","🐮","🐷","🐸","🐵","🐔","🐧","🐦","🦅","🦆","🦉","🐴","🦄","🐝","🐛","🦋","🐌","🐞","🐢","🐍","🦎","🐙","🦑","🦐","🦀","🐠","🐟","🐬","🐳","🐊","🐘","🦏","🐪","🦒","🐕","🐈","🐓","🦃","🦚","🦜","🐇","🦔","🐺","🐗"}', 'LOW'),
(2, '请点击所有的食物饮品', '{"🍎","🍐","🍊","🍋","🍌","🍉","🍇","🍓","🍒","🍑","🥭","🍍","🥥","🥝","🍅","🍆","🥑","🥦","🌽","🥕","🍞","🧀","🍳","🍔","🍟","🍕","🌮","🍣","🍜","🍩","🍪","🎂","🍫","🍭","☕","🍵","🧃","🥤","🍺","🍷"}', 'LOW'),
(3, '请点击所有的交通工具', '{"🚗","🚕","🚙","🚌","🏎","🚓","🚑","🚒","🚐","🚚","🚛","🚜","🚲","🛵","🏍","🚨","🚔","🚡","🚠","🚃","🚋","🚄","🚅","🚂","✈️","🛩","🚀","🛸","🚁","⛵","🚤","🛳","⛴","🚢"}', 'LOW'),
(4, '请点击所有的天气自然', '{"☀️","🌤","⛅","🌥","☁️","🌦","🌧","⛈","🌩","🌨","❄️","☃️","🌪","🌈","🌊","💧","🔥","⭐","🌟","✨","⚡","☄️","🌸","🌺","🌻","🌹","🌷","🌱","🌿","🍀","🍁","🍂","🍃","🌴","🌵"}', 'LOW');
INSERT INTO announcements (title, content, is_pinned, is_published, sort_order) VALUES
('tianai-captcha-enhanced 2.0.0 上线', '# tianai-captcha-enhanced
基于 tianai-captcha 开源版的增强版行为验证码平台
## 特性
- 16种验证码类型
- ML轨迹校验器(28维特征+14条规则)
- 对抗扰动防YOLO
- 行为风控引擎
- 端到端加密(AES-256+RSA-4096)
- 背景乱序/正弦扭曲/噪声注入
- IP黑名单+滑动窗口限流', TRUE, TRUE, 0);