图像识别高难度验证码接口文档
由于题目数据库较少,在此征题。
之前被管理说 DeepSeek 能识别,现在试过不行了。
:::info[注意] 本文代码由 DeepSeek 编写。
文章经过 DeepSeek 润色。 :::
概述
本验证码服务提供基于场景识别的智能验证码系统。
重要提醒:为了安全,建议不在客户端直接处理验证逻辑,而是将用户选择发送到您的服务端,由您的服务端转发给验证码平台进行验证。
基础信息
- 服务地址:
http://171.80.1.123:5000 - 协议:HTTP
- 响应格式:JSON
- 字符编码:UTF-8
安全建议
:::success[推荐结构]{open} 用户浏览器 → 您的服务端 → 验证码平台 → 您的服务端 → 用户浏览器 :::
:::warning[ 不推荐(存在安全风险)] 用户浏览器 → 验证码平台 → 用户浏览器 :::
推荐流程
- 用户访问您的网站
- 您的服务端请求验证码平台生成验证码
- 验证码平台返回验证码数据
- 您的服务端将验证码数据转发给客户端
- 用户选择答案后,客户端发送到您的服务端
- 您的服务端转发到验证码平台验证
- 验证码平台返回验证结果给您的服务端
- 您的服务端根据结果处理业务逻辑
API 接口
1. 健康检查
端点:GET /api/health
描述:检查服务状态和配置信息
请求:
GET /api/health HTTP/1.1
Host:171.80.1.123:5000
响应示例:
{
"status":"healthy",
"timestamp":"2024-01-01T12:00:00.000Z",
"questions_count":5,
"option_letters":["A", "B", "C", "D"],
"image_size":{
"configured":"600x650",
"needed":630,
"enough":true
}
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| status | string | 服务状态,healthy / error |
| timestamp | string | 服务器时间 |
| questions_count | int | 题库题目数量 |
| option_letters | array | 支持的选项字母 |
| image_size.configured | string | 图片配置尺寸 |
| image_size.needed | int | 所需最小高度 |
| image_size.enough | boolean | 配置高度是否足够 |
2. 生成验证码
端点:GET /api/captcha/generate
请求:
GET /api/captcha/generate HTTP/1.1
Host:171.80.1.123:5000
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| difficulty | int | 否 | 难度级别 (1-3),默认为随机 |
响应示例:
{
"success":true,
"captcha_id":"a1b2c3d4e5f6g7h8",
"image_base64":"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA...",
"image_size":{
"width":600,
"height":650,
"used_height":630
},
"expire_time":300,
"note":"请选择正确的选项字母(A/B/C/D)"
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| success | boolean | 请求是否成功 |
| captcha_id | string | 验证码会话 ID (32 字符) |
| image_base64 | string | base64 编码的验证码图片 |
| image_size.width | int | 图片宽度 (px) |
| image_size.height | int | 图片高度 (px) |
| image_size.used_height | int | 实际使用的高度 |
| expire_time | int | 验证码有效期 (秒) |
| note | string | 使用说明 |
安全注意事项:
captcha_id应该由您的服务端保存,不要暴露给客户端- 验证码图片通过您的服务端中转给客户端
- 不要将原始响应直接返回给客户端
3. 验证验证码
端点:POST /api/captcha/verify
描述:验证用户选择的答案
请求:
POST /api/captcha/verify HTTP/1.1
Host:171.80.1.123:5000
Content-Type:application/json
请求体:
{
"captcha_id":"a1b2c3d4e5f6g7h8",
"answer":"A"
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| captcha_id | string | 是 | 验证码会话 ID |
| answer | string | 是 | 用户选择的答案,必须为 A/B/C/D |
响应示例(成功):
{
"success":true,
"verified":true,
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"message":"验证成功"
}
响应示例(失败):
{
"success":true,
"verified":false,
"message":"答案错误"
}
响应示例(错误):
{
"success":false,
"error":"验证码已过期或不存在",
"code":404
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| success | boolean | 请求处理是否成功 |
| verified | boolean | 验证是否通过 |
| token | string | JWT 令牌(验证通过时返回) |
| message | string | 结果消息 |
| error | string | 错误信息(失败时) |
| code | int | HTTP 状态码(失败时) |
JWT 令牌解码示例:
{
"captcha_id":"a1b2c3d4e5f6g7h8",
"verified":true,
"exp":1704115200
}
4. 刷新验证码
端点:POST /api/captcha/verify(通过验证失效)
描述:没有专门的刷新接口,通过验证一个无效答案使当前验证码失效
方法:
- 使用当前
captcha_id发送一个无效答案(如X) - 然后重新调用生成接口
示例:
// 1. 使旧验证码失效
await fetch('http://171.80.1.123:5000/api/captcha/verify', {
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
captcha_id:old_captcha_id,
answer:'X' // 无效答案
})
});
// 2. 生成新验证码
await fetch('http://171.80.1.123:5000/api/captcha/generate');
状态码
| 状态码 | 说明 | 可能原因 |
|---|---|---|
| 200 | 成功 | 请求成功处理 |
| 400 | 错误请求 | 缺少必要参数、参数格式错误 |
| 404 | 未找到 | 验证码不存在或已过期 |
| 429 | 请求过多 | 超过频率限制 |
| 500 | 服务器错误 | 服务器内部错误 |
频率限制
- 生成验证码:60 次/分钟/IP(一般来说,这满足正常业务需求)
- 验证验证码:无限制(但验证后会话立即销毁)
- 健康检查:无限制
如果您业务实在过大超过频率限制,请联系我。
安全架构示例
您的服务端实现(Node.js 示例)
const express = require('express');
const axios = require('axios');
const app = express();
const CAPTCHA_SERVER = 'http://171.80.1.123:5000';
// 1. 生成验证码(服务端调用)
app.get('/api/my-captcha/generate', async (req, res) => {
try {
// 调用验证码平台
const response = await axios.get(`${CAPTCHA_SERVER}/api/captcha/generate`);
if (response.data.success) {
// 保存captcha_id到会话或数据库
req.session.captcha_id = response.data.captcha_id;
// 只返回图片给客户端,不返回captcha_id
res.json({
success:true,
image_base64:response.data.image_base64,
expire_time:response.data.expire_time
});
} else {
res.status(500).json({ error:'生成验证码失败' });
}
} catch (error) {
res.status(500).json({ error:'服务异常' });
}
});
// 2. 验证验证码(服务端转发)
app.post('/api/my-captcha/verify', async (req, res) => {
try {
const { answer } = req.body;
const captcha_id = req.session.captcha_id;
if (!captcha_id || !answer) {
return res.status(400).json({ error:'参数缺失' });
}
// 调用验证码平台验证
const response = await axios.post(`${CAPTCHA_SERVER}/api/captcha/verify`, {
captcha_id,
answer
});
// 清除会话中的验证码信息
delete req.session.captcha_id;
// 返回验证结果给客户端
res.json({
success:response.data.success,
verified:response.data.verified,
message:response.data.message
});
} catch (error) {
res.status(500).json({ error:'验证失败' });
}
});
// 3. 业务接口(受验证码保护)
app.post('/api/submit-form', async (req, res) => {
try {
const { formData, captcha_answer } = req.body;
const captcha_id = req.session.captcha_id;
// 先验证验证码
const verifyResponse = await axios.post(`${CAPTCHA_SERVER}/api/captcha/verify`, {
captcha_id,
answer:captcha_answer
});
if (!verifyResponse.data.verified) {
return res.status(403).json({ error:'验证码验证失败' });
}
// 验证通过,执行业务逻辑
// ... 处理formData ...
res.json({ success:true, message:'提交成功' });
} catch (error) {
res.status(500).json({ error:'处理失败' });
}
});
您的客户端实现
<script>
async function generateCaptcha() {
const response = await fetch('/api/my-captcha/generate');
const data = await response.json();
if (data.success) {
document.getElementById('captchaImage').src = data.image_base64;
startCountdown(data.expire_time);
}
}
async function submitForm() {
const formData = {
};
const captchaAnswer = document.querySelector('input[name="captcha"]:checked')?.value;
if (!captchaAnswer) {
alert('请选择验证码答案');
return;
}
const response = await fetch('/api/submit-form', {
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
formData,
captcha_answer:captchaAnswer
})
});
const result = await response.json();
if (result.success) {
alert('提交成功!');
} else {
alert(`提交失败:${result.error}`);
}
}
</script>
验证码特性
- 内容随机化:选项内容每次随机分配
- 视觉干扰:文字颜色、旋转、大小随机
- 时间限制:5 分钟有效期
- 一次性使用:验证后立即失效
- 无规律可循:选项位置固定但内容随机
集成步骤
第 1 步:环境检查
curl http://171.80.1.123:5000/api/health
第 2 步:服务端集成
- 在您的服务端添加验证码生成接口
- 在您的服务端添加验证码验证接口
- 将验证码集成到需要保护的业务接口
第 3 步:客户端集成
- 在需要验证的地方显示验证码
- 用户选择后提交到您的服务端
- 根据验证结果进行下一步操作
第 4 步:测试验证
- 测试正常流程
- 测试错误情况
- 测试性能表现
故障排除
常见问题
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 无法生成验证码 | 服务器离线 | 检查服务状态 |
| 验证总是失败 | captcha_id 过期 |
重新生成验证码 |
| 图片显示异常 | base64 格式错误 | 检查响应格式 |
| 响应缓慢 | 网络问题 | 检查网络连接 |
其他故障
请在洛谷联系我或发邮件至 [email protected]