Устранение неполадок

reCAPTCHA: ошибки и исправления проверки домена

reCAPTCHA проверяет, что токены используются в том же домене, для которого они были созданы. Если существует несоответствие между конфигурацией домена CAPTCHA и фактическим источником запроса, вы получаете ошибки проверки домена. Эти сбои происходят молчаливо — токен кажется действительным, но сервер его отклоняет. В этом руководстве описаны все сценарии ошибок, связанных с доменом, и способы их устранения.


Как работает проверка домена

Site owner registers reCAPTCHA → adds allowed domains (example.com, www.example.com)
    ↓
reCAPTCHA widget loads on example.com → matches allowed domain ✓
    ↓
Token generated with embedded hostname
    ↓
Server validates token via siteverify API
    ↓
Google checks: Does token hostname match allowed domains?
    ├─ YES → { "success": true, "hostname": "example.com" }
    └─ NO  → { "success": false, error or hostname mismatch }

Где проверяется домен

Контрольно-пропускной пункт Что проверено
На стороне клиента Виджет загружается только на разрешенных доменах (необязательно — можно отключить)
Генерация токена Имя хоста, встроенное в токен, соответствует источнику страницы
Проверка сервера siteverify возвращает имя хоста — сервер должен проверить его совпадение

Распространенные ошибки проверки домена

Ошибка 1: несоответствие имени хоста в ответе siteverify.

{
    "success": true,
    "hostname": "subdomain.example.com",
    "challenge_ts": "2025-01-15T10:30:00Z"
}

Токен действителен, но в поле hostname указан другой домен, чем ожидалось. Некоторые реализации сервера отвергают это:

# Server-side validation that checks hostname
def validate_token(token, secret_key, expected_hostname):
    result = requests.post(
        "https://www.google.com/recaptcha/api/siteverify",
        data={"secret": secret_key, "response": token},
    ).json()

    if not result.get("success"):
        return False

    # This check causes failures when hostnames don't match
    if result.get("hostname") != expected_hostname:
        return False  # Domain mismatch!

    return True

Причины:

  • Токен решен для www.example.com, но проверен на example.com.
  • Токен решен для staging.example.com, но проверен на example.com.
  • Прокси или CDN меняют видимое имя хоста

Исправление: Убедитесь, что pageurl в запросе решателя точно соответствует домену, куда будет отправлен токен.

Ошибка 2: виджет отказывается загружаться.

Виджет reCAPTCHA показывает ошибку или не отображается:

ERROR: Invalid domain for site key

Причины:

  • Разрешенные домены ключа сайта не включают домен текущей страницы.
  • Загрузка виджета с локального хоста или файла: протокол //
  • Использование IP-адреса вместо доменного имени

Исправление автоматизации. Это проблема конфигурации владельца сайта. Для решения убедитесь, что вы передали правильный pageurl, соответствующий разрешенному домену.

Ошибка 3: токен отклонен, несмотря на правильное решение

{
    "success": false,
    "error-codes": ["invalid-input-response"]
}

Токен был создан для домена, отличного от того, в котором он проверяется.

Распространенная причина автоматизации: pageurl, отправленный решателю, не соответствует фактическому целевому домену:

# WRONG: pageurl doesn't match actual target
submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": sitekey,
    "pageurl": "https://https://staging.example.com/qa-login",  # ← Must match actual domain
    "json": 1,
})

# But submitting token to:
requests.post("https://app.https://staging.example.com/qa-login", ...)  # Different subdomain!

Правила сопоставления доменов

Точное совпадение с подстановочным знаком

Проверка домена reCAPTCHA по умолчанию не является строгой проверкой субдомена. Поведение зависит от конфигурации владельца сайта:

Зарегистрированный домен Приемлемое происхождение
example.com example.com, www.example.com, sub.example.com (если подстановочный знак включен)
www.example.com Только www.example.com (если строго)
*.example.com Любой субдомен example.com
localhost Только localhost (для разработки)

Поведение имени хоста на стороне сервера

При проверке через siteverify hostname в ответе отражает страницу, на которой был сгенерирован токен. Сервер владельца сайта решает, принимать ли его:

# Permissive validation (accepts any subdomain)
def validate_permissive(token, secret, base_domain):
    result = requests.post(
        "https://www.google.com/recaptcha/api/siteverify",
        data={"secret": secret, "response": token},
    ).json()

    if not result.get("success"):
        return False

    hostname = result.get("hostname", "")
    return hostname == base_domain or hostname.endswith(f".{base_domain}")


# Strict validation (exact match only)
def validate_strict(token, secret, expected_hostname):
    result = requests.post(
        "https://www.google.com/recaptcha/api/siteverify",
        data={"secret": secret, "response": token},
    ).json()

    return result.get("success") and result.get("hostname") == expected_hostname

Исправление доменных ошибок в автоматизации

Исправление 1: точное совпадение URL-адреса страницы

Самое распространенное решение — убедиться, что pageurl соответствует фактической цели:

# Correct: pageurl matches where you'll submit the token
target_url = "https://www.https://staging.example.com/qa-login"

submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": "6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp",
    "pageurl": target_url,  # Must match the actual domain
    "json": 1,
})

Исправление 2. Обработка www и не-www

from urllib.parse import urlparse

def normalize_url(url):
    """Normalize URL for consistent domain matching."""
    parsed = urlparse(url)
    # Use exactly what the target site uses
    # Check if the site redirects www → non-www or vice versa
    return f"{parsed.scheme}://{parsed.netloc}{parsed.path}"

# Test which variant the site uses
response = requests.get("https://https://staging.example.com/qa-login", allow_redirects=True)
actual_url = response.url  # May be https://www.https://staging.example.com/qa-login after redirect

Исправление 3. Определите правильный домен из цепочки перенаправления.

Некоторые сайты перенаправляются через несколько доменов:

def get_final_url(url):
    """Follow redirects to find the actual CAPTCHA page domain."""
    response = requests.get(url, allow_redirects=True, timeout=15)
    return response.url

# Login URL might redirect:
# https://https://staging.example.com/qa-login → https://auth.https://staging.example.com/qa-login
final_url = get_final_url("https://https://staging.example.com/qa-login")
# Use final_url as pageurl for solver

Исправление 4. Извлеките домен из URL-адреса обратного вызова reCAPTCHA.

from bs4 import BeautifulSoup
from urllib.parse import urlparse

def extract_recaptcha_domain(html, page_url):
    """Extract the domain reCAPTCHA uses for token binding."""
    soup = BeautifulSoup(html, "html.parser")

    # Check for reCAPTCHA iframe
    iframe = soup.find("iframe", src=lambda s: s and "recaptcha" in s)
    if iframe:
        src = iframe.get("src", "")
        # The iframe URL may contain the domain parameter
        if "domain=" in src:
            # Extract domain from iframe URL
            pass

    # Default: use the page URL's domain
    return urlparse(page_url).netloc

Диагностический инструмент проверки домена

import requests
from urllib.parse import urlparse

class DomainDiagnostic:
    """Diagnose domain verification issues for reCAPTCHA solving."""

    def __init__(self, target_url):
        self.target_url = target_url
        self.issues = []

    def check_redirects(self):
        """Check if the URL redirects to a different domain."""
        try:
            response = requests.get(
                self.target_url, allow_redirects=True, timeout=15,
                headers={"User-Agent": "Mozilla/5.0 Chrome/120.0.0.0"},
            )
            final_url = response.url
            original_domain = urlparse(self.target_url).netloc
            final_domain = urlparse(final_url).netloc

            if original_domain != final_domain:
                self.issues.append({
                    "type": "redirect",
                    "message": f"Redirects from {original_domain} to {final_domain}",
                    "fix": f"Use pageurl: {final_url}",
                })

            return final_url
        except Exception as e:
            self.issues.append({"type": "error", "message": str(e)})
            return self.target_url

    def check_www_variant(self):
        """Check if www and non-www point to the same content."""
        parsed = urlparse(self.target_url)
        domain = parsed.netloc

        if domain.startswith("www."):
            alt_domain = domain[4:]
        else:
            alt_domain = f"www.{domain}"

        alt_url = self.target_url.replace(domain, alt_domain)

        try:
            alt_response = requests.get(alt_url, allow_redirects=True, timeout=10)
            alt_final = urlparse(alt_response.url).netloc

            if alt_final != domain and alt_final != alt_domain:
                self.issues.append({
                    "type": "www_redirect",
                    "message": f"{alt_domain} redirects to {alt_final}",
                })
        except Exception:
            pass

    def report(self):
        """Generate diagnostic report."""
        final_url = self.check_redirects()
        self.check_www_variant()

        print(f"Target URL: {self.target_url}")
        print(f"Final URL:  {final_url}")
        print(f"Use as pageurl: {final_url}")

        if self.issues:
            print("\nIssues found:")
            for issue in self.issues:
                print(f"  [{issue['type']}] {issue['message']}")
                if "fix" in issue:
                    print(f"  Fix: {issue['fix']}")
        else:
            print("\nNo domain issues detected.")


# Usage
diag = DomainDiagnostic("https://https://staging.example.com/qa-login")
diag.report()

Таблица устранения неполадок

Симптом Вероятная причина Диагностика Исправить
Токен всегда отклоняется pageurl не соответствует целевому домену Сравните pageurl решателя с фактическим доменом отправки Обновите URL-адрес страницы, чтобы он соответствовал
На www работает, на не www работает. Несоответствие варианта домена Проверьте поведение перенаправления Используйте вариант, который использует целевой сайт (следуйте перенаправлениям).
Иногда работает, иногда не работает CDN или балансировщик нагрузки обслуживают разные домены Проверьте, меняется ли домен в зависимости от запроса Используйте согласованный URL-адрес из цепочки переадресации.
Работает в браузере, не работает в скрипте Скрипт отправляется из другого источника Сравните строку URL-адреса браузера с URL-адресом страницы скрипта. Сопоставить конечный URL-адрес браузера
Корпоративный токен отклонен Неправильная привязка проекта или домена Убедитесь, что ключ корпоративного сайта соответствует домену Проверьте настройки домена корпоративной консоли

Часто задаваемые вопросы

CaptchaAI автоматически выполняет проверку домена?

CaptchaAI генерирует токены, привязанные к предоставленному вами pageurl. Вы должны убедиться, что этот URL-адрес соответствует домену, куда вы отправите токен. CaptchaAI не проверяет конфигурацию домена — он использует любой указанный вами URL-адрес страницы.

Могу ли я решить CAPTCHA для одного домена и использовать ее в другом?

Нет. Токены reCAPTCHA привязаны к домену, для которого они были созданы. Токен, сгенерированный для example.com, нельзя использовать в other-site.com. Даже разные поддомены могут дать сбой, если сайт строго проверяет имя хоста.

Почему мой токен работает при тестировании, но не работает в рабочей среде?

Распространенные причины: (1) При тестировании используется localhost с другими правилами домена, (2) В рабочей среде используется CDN с другим доменом, (3) В рабочей среде применяется более строгая проверка имени хоста, (4) В рабочей среде другой путь URL-адреса или цепочка перенаправления.

Имеет ли значение путь или только домен?

ReCAPTCHA проверяет только домен (имя хоста). Путь (/login, /signup) не влияет на проверку домена. Однако вам все равно следует использовать правильный полный URL-адрес pageurl, поскольку некоторые реализации решателя могут использовать его для других целей.


Краткое содержание

Проверка домена reCAPTCHA связывает токены с именем хоста, на котором они были сгенерированы. Наиболее распространенной ошибкой автоматизации является несоответствие pageurl — URL-адрес, передаваемыйCaptchaAIдолжен соответствовать домену, куда будет отправлен токен. Следуйте перенаправлениям, чтобы найти реальный домен, обрабатывать варианты с www и без www и использовать инструмент диагностики домена для выявления несоответствий перед решением.

Похожие статьи

  • Как решить обратный вызов Recaptcha V2 с помощью API
  • Cloudflare Turnstile Recaptcha V2. Обработка на той же площадке.
  • Распространенные ошибки и исправления капчи в виде сетки
Комментарии для этой статьи отключены.