EGOCaptcha Swagger

Сервис капчи

Выдаёт задачу-картинку и проверяет ответ человека. Нужен там, где форму можно дёргать роботом: регистрация, вход, восстановление пароля, отправка заявки.

Хранилища у сервиса нет: задача живёт 10 минут в памяти и гасится при первой же проверке — верной или неверной.

Живой пример

Та самая картинка, которую увидит человек:

Пример капчи

Шаг 1. Заказать задачу

Ключ не нужен: картинку всё равно показывают человеку.

POST https://captcha.egocoretest.ru/v1/captcha
Content-Type: application/json
X-Service-Name: egoid          # кто заказывает — сверится при проверке

{"purpose": "register"}        # зачем: свободная метка вашего сервиса
{
  "captcha_id": "3f2b…",
  "image_base64": "iVBORw0KGgo…",
  "image_url": "https://captcha.egocoretest.ru/v1/captcha/3f2b….png",
  "expires_in": 600,
  "length": 5
}

Вставляйте image_url в <img src> или image_base64 в data: — что удобнее. Картинку можно перезапрашивать: она не гасит задачу.

Шаг 2. Проверить ответ

Только со своего сервера и только с ключом сервиса. Ключ выдаём мы; он же определяет имя сервиса — оно должно совпасть с тем, что стояло в заголовке при заказе.

POST https://captcha.egocoretest.ru/v1/captcha/verify
Content-Type: application/json
X-Service-Key: ваш-ключ

{"captcha_id": "3f2b…", "answer": "k7m4x", "purpose": "register"}
200 {"ok": true}

400 {"error": {"code": "captcha_invalid", "message": "Код с картинки не подошёл"}}
400 {"error": {"code": "captcha_expired", "message": "Код с картинки устарел, обновите его"}}
401 {"error": {"code": "unauthorized",   "message": "Нужен ключ сервиса"}}
Задача одноразова. Любая проверка её гасит — и верная, и неверная. Иначе код перебирается по буквам за столько запросов, сколько нужно. После неудачи заказывайте новую картинку.

Пример на Python

import httpx

CAPTCHA = "https://captcha.egocoretest.ru"

async def issue() -> dict:
    async with httpx.AsyncClient(timeout=4.0) as client:
        response = await client.post(
            f"{CAPTCHA}/v1/captcha",
            json={"purpose": "register"},
            headers={"X-Service-Name": "мой-сервис"},
        )
    return response.json()

async def check(captcha_id: str, answer: str) -> bool:
    async with httpx.AsyncClient(timeout=4.0) as client:
        response = await client.post(
            f"{CAPTCHA}/v1/captcha/verify",
            json={"captcha_id": captcha_id, "answer": answer, "purpose": "register"},
            headers={"X-Service-Key": SERVICE_KEY},
        )
    return response.status_code == 200

Ограничения и правила

Срок задачи
600 секунд
Длина кода
5 символов, только строчные буквы и цифры
Регистр ответа
не важен, пробелы по краям срезаются
Выдача картинок
не больше 30 в минуту с адреса
Таймаут вызова
ставьте 4 секунды: капча не должна задерживать вашу форму

Алфавит намеренно без пар, которые путаются при повороте: нет 0/o, 1/l/i/j, 6/9, 2/z, 5/s. Человек не должен гадать.

Что делать, если сервис недоступен

Решайте сами и осознанно. Для регистрации разумно не пропускать: без капчи форма открыта роботам. Для действия вошедшего человека — наоборот, пропустить: он уже доказал, что он человек, и падение вспомогательного сервиса не должно ломать работу.