Используйте solvethree в представлении Django

Автор: solvethree4 мин на чтение

Создайте задачу в POST-представлении, верните её ID и предоставьте вызывающей стороне возможность получать её статус. Не держите запрос создания открытым до завершения решения.

Предлагаемые представления используют настроенный целевой ресурс reCAPTCHA Enterprise и один прокси. Они предназначены для существующего проекта Django с включённой аутентификацией и стандартным промежуточным ПО CSRF.

На этой странице

Установите SDK и настройте целевой ресурс

  1. 1.

    Установите SDK в окружении Django

    Официальный SDK требует Python 3.10+. В окружении, где работает Django, выполните python -m pip install https://solvethree.com/downloads/solvethree_sdk-0.1.0-py3-none-any.whl.

  2. 2.

    Задайте переменные окружения сервера

    Задайте в SOLVETHREE_API_KEY API-ключ вашего рабочего пространства, в CAPTCHA_SITE — имя хоста целевого ресурса, а не полный URL, а в SOLVETHREE_PROXY — прокси для решения и последующей отправки запроса целевому ресурсу. Храните API-ключ и учётные данные прокси на сервере.

  3. 3.

    Активируйте профиль сайта

    Настройте в консоли активный профиль для этого имени хоста, доступный вашему рабочему пространству. Передача имени хоста и действия не создаёт профиль. См. настройку профиля сайта.

В примере действие фиксировано как login, а настройки целевого ресурса от вызывающей стороны не принимаются. Измените это действие, если настроенный целевой ресурс требует другого. Запрос использует режим enterprise-v3 по умолчанию; ему нужны site, action и ровно одно из полей proxy или proxyCandidates, а не type или url.

Добавьте представления с проверкой аутентификации

Django · представления с аутентификацией и стандартной защитой CSRF
# views.py in an existing Django project with authentication/CSRF configured.
import os
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_GET, require_POST
from solvethree import Solvethree, SolvethreeError

def client():
    return Solvethree(os.environ["SOLVETHREE_API_KEY"])

@login_required
@require_POST
def create_captcha(request):
    task = {"site": os.environ["CAPTCHA_SITE"], "action": "login", "proxy": os.environ["SOLVETHREE_PROXY"]}
    if request.headers.get("X-Request-ID"):
        task["requestId"] = request.headers["X-Request-ID"]
    try:
        return JsonResponse(client().create_task(task, wait_ms=0, timeout=20))
    except ValueError:
        return JsonResponse({"error": "Invalid task input"}, status=400)
    except SolvethreeError as error:
        return JsonResponse({"requestId": error.request_id, "taskId": error.task_id}, status=502)

@login_required
@require_GET
def get_captcha(request, task_id):
    try:
        return JsonResponse(client().get_task(task_id, wait_ms=15000, timeout=25))
    except ValueError:
        return JsonResponse({"error": "Invalid task ID"}, status=400)
    except SolvethreeError as error:
        return JsonResponse({"requestId": error.request_id, "taskId": error.task_id}, status=502)

# urls.py: import these views and add to urlpatterns:
# path("captcha/tasks", create_captcha),
# path("captcha/tasks/<str:task_id>", get_captcha),

create_task использует wait_ms=0, поэтому возвращает задачу, не дожидаясь завершения решения. Тайм-аут его HTTP-вызова составляет 20 секунд. Представление получения задачи может ждать её обновления до 15 секунд при тайм-ауте HTTP в 25 секунд. Это синхронные вызовы SDK: во время ожидания запрос получения по-прежнему занимает рабочий процесс Django.

login_required ограничивает доступ пользователями, вошедшими в систему; декораторы методов разрешают POST для создания и GET для получения. Сохраните стандартную защиту CSRF в Django и передавайте её CSRF-токен при отправке POST. Не добавляйте csrf_exempt.

Подключите маршруты и запустите Django

  1. 1.

    Обновите существующий URLconf

    Импортируйте path из django.urls, а также create_captcha и get_captcha из модуля представлений вашего приложения. Добавьте две записи маршрутов, показанные внизу примера, в существующий urlpatterns. Если вы используете URLconf приложения, убедитесь, что URLconf проекта подключает его.

  2. 2.

    Запустите сервер разработки

    Убедитесь, что переменные окружения доступны процессу, и выполните python manage.py runserver из каталога, содержащего manage.py. Перед вызовом эндпоинтов войдите в систему через существующий механизм входа вашего проекта.

  3. 3.

    Используйте зарегистрированные пути

    Без внешнего префикса URL создание выполняется через POST /captcha/tasks, а получение — через GET /captcha/tasks/<task_id>. Предлагаемые маршруты не имеют завершающего слеша. Учитывайте любой префикс, добавленный URLconf вашего проекта.

Создайте задачу один раз, затем получайте её данные

  1. 1.

    Сохраните ID перед отправкой POST

    Выбирайте новый X-Request-ID для каждой логической задачи и сохраняйте его, пока исход создания не станет известен. Используйте 1–64 ASCII-буквы, цифры, символы подчёркивания или дефисы. Представление передаёт этот заголовок как requestId задачи.

  2. 2.

    Проверьте успешность HTTP-запроса до проверки статуса задачи

    Пример возвращает HTTP 400 при перехваченных ошибках проверки входных данных и 502 при перехваченных ошибках SDK. Успешный ответ содержит данные задачи; прочитайте её id и status. Успешный HTTP-ответ означает, что запрос выполнен, а не что токен готов.

  3. 3.

    Запрашивайте задачу до её завершения

    Вызывайте GET-эндпоинт с возвращённым ID задачи. Продолжайте при статусе pending или solving. При ready используйте решение. При failed прекратите опрос и проверьте errorCode и error; за неудачные решения средства возвращаются. Исправляйте некорректные входные данные, а не повторяйте запросы с ними без изменений.

  4. 4.

    Восстановите результат создания с неизвестным исходом

    Если время ожидания POST истекло или он вернул ошибку SDK, не создавайте сразу другую задачу с новым ID. Получите существующую задачу, если её ID известен. В противном случае повторите POST с исходным X-Request-ID и неизменными входными данными задачи, чтобы восстановить доступ к ней. Повторное использование этого ID с другими входными данными вызывает конфликт — в том числе при изменении настроенного имени хоста, действия или прокси.

Ответ с ошибкой SDK включает requestId и taskId из исключения для диагностики. Сохраняйте исходный X-Request-ID вызывающей стороны отдельно, чтобы восстановление не зависело от получения этого ответа. Об обработке сбоев см. ошибки CAPTCHA API.

Отправляйте токен с тем же прокси и возвращёнными параметрами идентификации

Только задача со статусом ready содержит пригодное к использованию решение. Целевому ресурсу нужно отправлять значение solution.token, а не ID задачи. Используйте возвращённые параметры идентификации браузера solution.userAgent и solution.secChUa вместе с исходным прокси, настроенным в SOLVETHREE_PROXY.

Эти представления ничего не отправляют целевому ресурсу. Ваш код отправки должен сохранять этот прокси и применять возвращённые параметры идентификации; передача токена в постороннюю сессию браузера не делает этого автоматически. Храните учётные данные прокси на сервере и не используйте решение с другим URL целевого ресурса или другими параметрами идентификации браузера.

Запустите первую задачу.

Начните с $5 на балансе рабочего пространства.

Создать рабочее пространство
Используйте solvethree в представлении Django · solvethree