Troubleshooting

Cloudflare Turnstile 403 Token Gönderiminden Sonra: Düzeltme Kılavuzu

Geçerli bir Turnstile token'ı aldınız ama sunucu hâlâ 403 Forbidden dönüyorsa, ilk refleksinizi tersine çevirin: sorun neredeyse hiçbir zaman token'ın kendisinde değildir. 403 çoğu zaman, çözümü tamamladıktan sonra oturum çerezlerini, istek başlıklarını ya da IP tutarlılığını doğru taşımadığınız anlamına gelir. Aşağıda beş temel nedeni görülme sıklığına göre ele alıyor ve her birini birkaç dakikada ayırt etmenizi sağlayan pratik bir yol veriyoruz.

Kod değiştirmeden önce 60 saniyelik triyaj

Satır satır kod kurcalamaya başlamadan önce yanıtı okuyun ve şu üç şeyi hızlıca kontrol edin:

  • Yanıt başlıklarında Server: cloudflare yoksa reddi uygulama katmanı vermiştir; form alan adını kontrol edin.
  • Server: cloudflare var ve gövde yeniden Turnstile widget'ını gösteriyorsa, çözümden gönderime kadar geçen süreye bakın — 240 saniyeyi aştıysa token büyük olasılıkla eskimiştir.
  • Süre kısa ama sayfa tam ekran bir bekleme animasyonu gösteriyorsa, karşınızdaki Turnstile değil Cloudflare doğrulama akışıdır.

Bu üç kontrol vakaların çoğunu tek başına eler; geri kalanı için aşağıdaki nedenler tablosuna ve ilgili bölümlere geçin.

Geçerli token'a rağmen neden 403 alırsınız

Neden Görülme sıklığı
qa_session_cookie çerezi eksik Çok yaygın
Token'ın süresi doldu Yaygın
Yanlış gönderim uç noktası Yaygın
İstek başlıkları eksik Orta
Çözme ve gönderim arasında IP uyuşmazlığı Orta
Cloudflare doğrulama akışı (Turnstile değil) Sık karıştırılır

Turnstile, doğrulama sırasında çerezleri ayarlar. Bu çerezleri sonraki isteğinize eklemezseniz Cloudflare sizi engeller. Bu yüzden çözümün ardından gelen her istek aynı requests.Session üzerinden gitmelidir.

import requests

session = requests.Session()

# Step 1: Load the page to get initial cookies
session.get("https://example.com")

# Step 2: Solve Turnstile
token = solve_turnstile(
    api_key="YOUR_API_KEY",
    sitekey="TURNSTILE_SITEKEY",
    pageurl="https://example.com",
)

# Step 3: Submit token to the validation endpoint
# This sets qa_session_cookie cookie
resp = session.post("https://example.com/api/verify", data={
    "cf-turnstile-response": token,
}, headers={
    "Content-Type": "application/x-www-form-urlencoded",
    "Origin": "https://example.com",
    "Referer": "https://example.com/",
})

# Step 4: Now make your actual request WITH the session cookies
resp = session.get("https://example.com/protected-page")
print(resp.status_code)  # Should be 200 now

Bu bölümde iki nokta çoğu 403'ü açıklar:

  • Çözüm, gönderim ve sonraki tüm istekler tek bir Session üzerinden gitmelidir.
  • Çerez yalnızca doğrulama uç noktasından döner; sayfayı yükleyen ilk GET bunu ayarlamaz.

Neden 2: Token'ın süresi doldu

Turnstile token'larının ömrü yaklaşık 300 saniyedir; yine de en iyi sonuç için token'ı hemen kullanın. Çözüm ile gönderim arasında dört dakikadan uzun beklerseniz token'ı yeniden çözmek daha güvenlidir.

import time

# Solve
start = time.time()
token = solve_turnstile(...)
solve_time = time.time() - start

# Check if token is still fresh
if solve_time > 240:  # > 4 minutes is risky
    print("Token may be too old, solving again...")
    token = solve_turnstile(...)

# Submit immediately
submit_token(token)

Neden 3: Yanlış gönderim yöntemi

Token'ı göndermeden önce sitenin bu token'ı tam olarak nasıl beklediğini belirleyin:

# Some sites use a hidden form field
data = {
    "cf-turnstile-response": token,
    "username": "user",
    "password": "pass",
}

# Some sites use a custom header
headers = {
    "X-Turnstile-Token": token,
}

# Some sites use JSON body
json_data = {
    "turnstileToken": token,
    "email": "user@example.com",
}

Doğru alan adını DevTools ile birkaç adımda bulursunuz:

  1. Tarayıcı DevTools → Ağ (Network) sekmesini açın
  2. Turnstile doğrulamasını elle tamamlayın
  3. Form gönderim isteğini bulun
  4. Token alan adı için istek gövdesini inceleyin

Neden 4: Eksik başlıklar

Cloudflare, istek başlıklarını tutarlılık açısından denetler. User-Agent, Origin ve Referer değerleri tarayıcının gönderdikleriyle eşleşmezse geçerli bir token bile 403 ile dönebilir.

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Origin": "https://example.com",
    "Referer": "https://staging.example.com/qa-login",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "same-origin",
}

session.headers.update(headers)

Neden 5: Cloudflare doğrulama akışı mı, Turnstile mı?

Turnstile ile Cloudflare doğrulama akışı birbirinden farklı sistemlerdir ve farklı bir yöntem gerektirir:

Özellik Turnstile Cloudflare doğrulama akışı
Widget Sayfada görünür onay kutusu Tam sayfa doğrulama ekranı
CaptchaAI yöntemi turnstile cloudflare_challenge
Token alanı cf-turnstile-response Yok (çerez tabanlı)

Tam sayfa bir doğrulama ekranı görüyorsanız turnstile yerine method=cloudflare_challenge kullanın.

Uçtan uca çalışan örnek

Aşağıdaki fonksiyon, sitekey çıkarımından token gönderimine kadar tüm akışı tek bir oturumda toplar; çerezler böylece korunur ve sonraki isteklere taşınır:

import requests
import time
import re


def solve_turnstile_and_access(target_url, api_key):
    """Complete flow: solve Turnstile and access protected page."""
    session = requests.Session()
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    })

    # Load page, get cookies and sitekey
    resp = session.get(target_url)
    match = re.search(r'data-sitekey="([^"]+)"', resp.text)
    if not match:
        raise RuntimeError("Turnstile sitekey not found")

    sitekey = match.group(1)

    # Solve via CaptchaAI
    submit_resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": api_key,
        "method": "turnstile",
        "sitekey": sitekey,
        "pageurl": target_url,
        "json": 1,
    }, timeout=30)
    task_id = submit_resp.json()["request"]

    # Poll
    for _ in range(12):
        time.sleep(5)
        poll = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key, "action": "get",
            "id": task_id, "json": 1,
        }, timeout=15)
        data = poll.json()
        if data.get("status") == 1:
            token = data["request"]
            break
    else:
        raise TimeoutError("Solve timeout")

    # Submit token using the same session
    form_resp = session.post(target_url, data={
        "cf-turnstile-response": token,
    }, headers={
        "Origin": f"https://{requests.utils.urlparse(target_url).netloc}",
        "Referer": target_url,
    })

    return session, form_resp


# Usage
session, resp = solve_turnstile_and_access(
    "https://staging.example.com/qa-login",
    "YOUR_API_KEY",
)
# session now has valid cookies for subsequent requests

Hızlı sorun giderme tablosu

En sık görülen dört durum ve doğrudan uygulanacak düzeltmeleri:

Sorun Neden Düzeltme
Geçerli token'a rağmen 403 Eksik oturum çerezleri Tüm istekler için aynı oturumu kullanın
Sonraki sayfalarda 403 qa_session_cookie ayarlanmadı Token doğrulaması çerez döndürmeli
Bir kez çalışıp sonra 403 Çerezin süresi doldu Taze çerez için yeniden çözün
Her zaman 403 Turnstile değil, tam sayfa doğrulama cloudflare_challenge yöntemini kullanın

Gerçek bir senaryo: yalnızca ikinci istekte 403

Türkiye'deki bir e-ticaret ekibinin, ödeme adımını staging.example.com üzerinde test eden QA hattını düşünün. Boru hattı Turnstile token'ını gönderiyor, form gönderimi 200 OK dönüyor ve korumalı sayfa geliyor. İki dakika sonra aynı akış /api/orders uç noktasını çağırınca 403 alıyor. Ekip önce token süresini suçladı; oysa token ilk gönderimden sonra zaten atılmıştı.

Kök neden: HTTP istemcisi her istek için bir yardımcı fonksiyonun içinde yeniden oluşturuluyordu. Her yeni istek boş bir çerez kabıyla açıldığı için ilk yanıtta ayarlanan qa_session_cookie ikinci isteğe hiç ulaşmadı.

Düzeltme: requests.Session() nesnesini yardımcı fonksiyonun dışına taşıyın ve parametre olarak geçirin. Korumalı origin'e yapılan her çağrı aynı oturumu kullanmalıdır. Token'ı tekrar göndermeniz gerekmez — sizi ileri taşıyan şey çerezdir. KVKK kapsamındaki kişisel verilerle çalışıyorsanız bu testleri yalnızca yetkili QA ortamlarında yürütün.

Destek talebi açmadan önce kontrol listesi

Bildirilen 403'lerin çoğu aşağıdaki listede yakalanır; solver'ı suçlamadan önce hepsini geçin:

  • Çözüm ve gönderim sırasında aynı User-Agent değeri kullanıldı
  • Çözüm ve gönderim aynı çıkış IP'sinden yapıldı (ya da proxy oturum düzeyinde sabitlendi)
  • Origin ve Referer başlıkları hedef sayfa URL'siyle eşleşiyor
  • Token, alındıktan sonraki 240 saniye içinde gönderildi
  • Token yalnızca bir kez gönderildi (Turnstile token'ları tek kullanımlıktır)
  • Form alan adı DevTools'ta doğrulandı (cf-turnstile-response mü, özel bir ad mı?)
  • requests.Session() çözüm → gönderim → sonraki isteklerde yeniden kullanıldı
  • data-sitekey her çalıştırmada yeniden çıkarıldı (sitekey'ler değişebilir)
  • Sayfanın gerçekten Turnstile sunduğu, tam sayfa doğrulama olmadığı doğrulandı
  • Sunucu, gönderimden sonra Set-Cookie ile çerez döndürdü

Sık sorulan sorular

Token geçerli olduğu hâlde neden 403 alıyorum?

Çünkü 403'ü çoğunlukla token değil, çözümden sonra taşınamayan oturum çerezleri tetikler. Çözüm ile sonraki isteklerin aynı oturumu, aynı User-Agent'ı ve aynı IP'yi kullandığından emin olun.

Turnstile token'ı ne kadar süre geçerli kalır?

Yaklaşık 300 saniye. Güvenli tarafta kalmak için token'ı aldıktan sonraki 240 saniye içinde gönderin; daha uzun beklediyseniz yeniden çözün.

Aynı oturumu her istekte kullanmak neden bu kadar önemli?

Çünkü sizi korumalı sayfada tutan şey token değil, doğrulamadan sonra ayarlanan çerezdir. Her seferinde yeni bir istemci açarsanız çerez kabı boş kalır ve 403 alırsınız.

Proxy kullanmadan Turnstile çözebilir miyim?

Çoğu durumda evet. Yalnızca site IP tutarlılığını denetliyorsa proxy'yi oturum düzeyinde sabitleyin; çözüm ve gönderim aynı IP'den gitmelidir.

İlgili kılavuzlar

403 döngüsünü kırın — Turnstile'ı CaptchaAI ile çözün.

Bu makale için yorumlar devre dışı bırakılmıştır.