Интеграции

Интеграция хранилища для управления ключами API CaptchaAI

Жестко запрограммированные ключи API в исходном коде представляют собой угрозу безопасности. HashiCorp Vault централизует управление секретами — вашCaptchaAIКлюч API хранится в зашифрованном виде, извлекается во время выполнения, и каждый доступ регистрируется. В этом руководстве показано, как интегрировать Vault в процесс решения CAPTCHA.

Почему Vault для ключей API CAPTCHA

Без хранилища С хранилищем
Ключ API в файле или коде .env Ключ хранится в зашифрованном виде в Vault.
Ключ передан через Slack или по электронной почте. Доступ через аутентифицированный API
Нет доступа к контрольному журналу Каждое чтение регистрируется с идентификатором
Ручное вращение ключа Поддержка автоматической ротации
Один и тот же ключ в разных средах Ключи для каждой среды с политиками

Предварительные условия

  • Сервер HashiCorp Vault (локальное размещение или HCP Vault)
  • Доступ к Vault CLI или API
  • CaptchaAI API-ключ
  • Python 3.8+ или Node.js 18+

Сохраните ключ API в Vault.

# Enable the KV secrets engine (if not already enabled)
vault secrets enable -path=secret kv-v2

# Store the CaptchaAI API key
vault kv put secret/captchaai api_key="YOUR_API_KEY"

# Verify
vault kv get secret/captchaai

Создайте политику хранилища

Ограничьте работникам CAPTCHA доступ только для чтения:

# captcha-worker-policy.hcl
path "secret/data/captchaai" {
  capabilities = ["read"]
}

path "secret/metadata/captchaai" {
  capabilities = ["read"]
}

Примените политику:

vault policy write captcha-worker captcha-worker-policy.hcl

Интеграция Python

# vault_solver.py
import os
import time
import hvac
import requests

# Connect to Vault
vault_client = hvac.Client(
    url=os.environ.get("VAULT_ADDR", "http://127.0.0.1:8200"),
    token=os.environ.get("VAULT_TOKEN"),
)

def get_api_key():
    """Retrieve CaptchaAI API key from Vault."""
    secret = vault_client.secrets.kv.v2.read_secret_version(
        path="captchaai",
        mount_point="secret",
    )
    return secret["data"]["data"]["api_key"]

class CaptchaSolver:
    """CAPTCHA solver with Vault-managed credentials."""

    def __init__(self):
        self.api_key = get_api_key()
        self.session = requests.Session()
        self._key_fetched_at = time.time()
        self._key_refresh_interval = 3600  # Re-fetch key hourly

    def _refresh_key_if_needed(self):
        """Periodically refresh the key from Vault."""
        if time.time() - self._key_fetched_at > self._key_refresh_interval:
            self.api_key = get_api_key()
            self._key_fetched_at = time.time()

    def solve(self, sitekey, pageurl):
        """Solve reCAPTCHA v2 using Vault-managed key."""
        self._refresh_key_if_needed()

        # Submit
        resp = self.session.get("https://ocr.captchaai.com/in.php", params={
            "key": self.api_key,
            "method": "userrecaptcha",
            "googlekey": sitekey,
            "pageurl": pageurl,
            "json": "1",
        })
        result = resp.json()

        if result.get("status") != 1:
            raise Exception(f"Submit failed: {result.get('request')}")

        task_id = result["request"]
        time.sleep(15)

        for _ in range(25):
            poll = self.session.get("https://ocr.captchaai.com/res.php", params={
                "key": self.api_key,
                "action": "get",
                "id": task_id,
                "json": "1",
            })
            poll_result = poll.json()

            if poll_result.get("status") == 1:
                return poll_result["request"]
            if poll_result.get("request") != "CAPCHA_NOT_READY":
                raise Exception(f"Error: {poll_result.get('request')}")

            time.sleep(5)

        raise Exception("Timeout")

# Usage
solver = CaptchaSolver()
token = solver.solve(
    "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
    "https://www.google.com/recaptcha/api2/demo"
)
print(f"Token: {token[:30]}...")

Интеграция JavaScript

// vault_solver.js
const axios = require('axios');

const VAULT_ADDR = process.env.VAULT_ADDR || 'http://127.0.0.1:8200';
const VAULT_TOKEN = process.env.VAULT_TOKEN;

async function getApiKey() {
  const resp = await axios.get(
    `${VAULT_ADDR}/v1/secret/data/captchaai`,
    { headers: { 'X-Vault-Token': VAULT_TOKEN } }
  );
  return resp.data.data.data.api_key;
}

class CaptchaSolver {
  constructor() {
    this.apiKey = null;
    this.keyFetchedAt = 0;
    this.refreshInterval = 3600000; // 1 hour
  }

  async init() {
    this.apiKey = await getApiKey();
    this.keyFetchedAt = Date.now();
  }

  async refreshKeyIfNeeded() {
    if (Date.now() - this.keyFetchedAt > this.refreshInterval) {
      this.apiKey = await getApiKey();
      this.keyFetchedAt = Date.now();
    }
  }

  async solve(sitekey, pageurl) {
    await this.refreshKeyIfNeeded();

    const submit = await axios.get('https://ocr.captchaai.com/in.php', {
      params: {
        key: this.apiKey, method: 'userrecaptcha',
        googlekey: sitekey, pageurl, json: '1',
      },
    });

    if (submit.data.status !== 1) throw new Error(submit.data.request);
    const taskId = submit.data.request;

    await new Promise(r => setTimeout(r, 15000));

    for (let i = 0; i < 25; i++) {
      const poll = await axios.get('https://ocr.captchaai.com/res.php', {
        params: { key: this.apiKey, action: 'get', id: taskId, json: '1' },
      });

      if (poll.data.status === 1) return poll.data.request;
      if (poll.data.request !== 'CAPCHA_NOT_READY') throw new Error(poll.data.request);
      await new Promise(r => setTimeout(r, 5000));
    }
    throw new Error('Timeout');
  }
}

(async () => {
  const solver = new CaptchaSolver();
  await solver.init();

  const token = await solver.solve(
    '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
    'https://www.google.com/recaptcha/api2/demo'
  );
  console.log(`Token: ${token.slice(0, 30)}...`);
})();

Методы аутентификации

Vault поддерживает несколько методов аутентификации для работников:

Метод подходящий для Настраивать
Токен Разработка, CI/CD VAULT_TOKEN переменная окружения
AppRole Производственные услуги Идентификатор роли + секретный идентификатор
Кубернетес Рабочие нагрузки K8s Сервисный аккаунт JWT
АВС ИАМ EC2/Lambda рабочие Роль экземпляра

Пример AppRole (рекомендуется для рабочей среды)

# AppRole authentication — no static token needed
vault_client = hvac.Client(url=os.environ["VAULT_ADDR"])
vault_client.auth.approle.login(
    role_id=os.environ["VAULT_ROLE_ID"],
    secret_id=os.environ["VAULT_SECRET_ID"],
)

# Now read the secret
secret = vault_client.secrets.kv.v2.read_secret_version(path="captchaai")
api_key = secret["data"]["data"]["api_key"]

Рабочий процесс ротации ключей

  1. Создайте новый ключ API CaptchaAI на панели инструментов CaptchaAI.
  2. Обновить хранилище: vault kv put secret/captchaai api_key="NEW_KEY"
  3. Сотрудники автоматически получают новый ключ при следующем цикле обновления.
  4. Отозвать старый ключ на панели управления CaptchaAI после того, как все рабочие обновятся.

Никаких изменений кода или развертываний не требуется.

Поиск неисправностей

| Проблема | Причина | Исправить |


Следующие шаги

  • CaptchaAI Quickstart: ваше первое решение CAPTCHA за 5 минут
  • Как решить reCAPTCHA v2 через API: пошаговое руководство
  • Как решить Cloudflare Turnstile через API
  • Как решить GeeTest v3 с помощью API
Комментарии для этой статьи отключены.