Blog / Makaleler

Google reCAPTCHA v2 invisible entegrasyonu

Bu yazı 2022 yılından. Anlatılan sürümler, fiyatlar ve adresler o günden bu yana değişmiş olabilir.

Merhaba. Bugün yazımızda sitelerimizde istenmeyen spam mesajlarla ve formlar üzerinde oluşan güvenlik ihlalleriyle nasıl başa çıkabileceğimiz konusunu ele alacağız. Bu güvenli ortamı bize sağlaması için Google'ın bir servisi olan reCAPTCHA hizmetini nasıl formlarımıza entegre edebileceğimizi öğreneceğiz.

Güncelleme (Kasım 2026): Bu yazıyı 2022'de yazmıştım. O günden bu yana Google reCAPTCHA anahtarlarını Google Cloud projelerine taşıdı, anahtar oluşturma ekranı biraz değişti. Kodda da eksik ve güvensiz kısımlar vardı, onları düzelttim. İndirme dosyası da güncel.

Anlatıma başlamadan önce kısaca reCAPTCHA hizmetinden bahsetmek gerekirse; formu gönderen kişinin sayfadaki davranışlarına bakarak insan mı yoksa bot mu olduğunu tahmin eden bir Google servisi. Bot olduğunu düşündüğü istekleri durduruyor, böylece formlarınıza otomatik spam gönderilmesinin önüne geçiyor.

google recaptcha

Biz bugün bu yazıda yukarıdaki görselin aksine sitemizdeki tasarım estetiğini bozmamak için gizli, sitedeki adıyla invisible reCAPTCHA kullanacağız. Yani kullanıcı "Ben robot değilim" kutucuğunu hiç görmeyecek. Ziyaretçi formu gönderdiğinde Google arka planda kontrolünü yapıyor. Her şey normal görünüyorsa form doğrudan gidiyor, bir şeylerden şüphelenirse ekrana "trafik ışıklarını seçin" gibi bir resim doğrulaması çıkarıyor. Normal bir ziyaretçi çoğu zaman hiçbir şey görmeden formu gönderiyor.

Entegrasyon iki parçadan oluşuyor:

  • Front-end: Formun bulunduğu sayfa. Ziyaretçi Gönder'e basınca Google'dan bir doğrulama kodu (token) alıyor ve formla birlikte gönderiyor.
  • Back-end: Formun gittiği PHP dosyası. Gelen kodu Google'a sorup gerçekten geçerli mi diye kontrol ediyor.

İkisi de şart. Sadece front-end kısmını yaparsanız bot formu doğrudan PHP dosyanıza gönderip korumayı atlayabilir.

Başlangıç aşaması

Google reCAPTCHA yönetim paneline giderek web sitemiz için yeni bir anahtar oluşturalım. Google artık anahtarları Google Cloud projelerine bağlı tuttuğu için bu bağlantı sizi Google Cloud konsoluna da yönlendirebilir. Ekran biraz farklı görünse de seçmeniz gerekenler aynı.

  • Etiket: Sitenizin adını girebilirsiniz, sadece sizin listede tanımanız için.
  • reCAPTCHA türü: reCAPTCHA v2 yapıyoruz, altında açılan seçeneklerden Görünmez reCAPTCHA rozeti olanı seçiyoruz.
  • Alan adları: Sitenizin domain adını girin, örneğin alifurkan.org. Kendi bilgisayarınızda deneme yapacaksanız buraya localhost da ekleyin, yoksa denerken hata alırsınız.

Hizmet sözleşmesini kabul edip Gönder butonuna basıyoruz. Oluşturduktan sonra size 2 adet anahtar verecek:

  • Site anahtarı (site key): Front-end kısmında, yani formun bulunduğu sayfada kullanacağız. Herkese açık bir anahtar, sayfanın kaynak kodunda görünmesi sorun değil.
  • Gizli anahtar (secret key): Back-end kısmında, yani PHP dosyasında kullanacağız. Bu anahtarı kimseyle paylaşmayın, GitHub gibi herkese açık yerlere yüklemeyin.

Bunları kenara kaydedelim, birazdan kullanacağız.

İkinci aşama: Front-end

Front-end kısmının entegrasyonunu göstermek adına bir deneme formu oluşturacağım. Bu dosyanın adı index.php olsun.

HTML
<!DOCTYPE html>
<html lang="tr">
<head>
 <meta charset="utf-8">
 <title>reCAPTCHA deneme formu</title>
 <script src="https://www.google.com/recaptcha/api.js" async defer></script>
 <script>
  function onSubmit(token) {
   document.getElementById('reCaptchaForm').submit();
  }
 </script>
</head>
<body>
<form action="gonder.php" id="reCaptchaForm" method="post" autocomplete="off">
 <input type="text" name="ad" placeholder="Adınız">
 <button class="g-recaptcha" data-sitekey="SITE_ANAHTARINIZ" data-callback="onSubmit">Gönder</button>
</form>
</body>
</html>

Kodda ne olduğunu sırayla anlatayım:

  • Head etiketleri arasındaki ilk satır reCAPTCHA'nın Google'daki dosyasını sayfamıza çağırıyor.
  • Gönder butonuna verdiğimiz g-recaptcha sınıfı, butonu reCAPTCHA'ya bağlıyor. Ziyaretçi butona bastığında form hemen gitmiyor, önce Google kontrolünü yapıyor.
  • Kontrol bitince Google data-callback kısmına yazdığımız onSubmit fonksiyonunu çalıştırıyor. Bu fonksiyon da head kısmına yazdığım ufak JavaScript kodu, formu gönderiyor. Google aldığı doğrulama kodunu forma g-recaptcha-response adında gizli bir alan olarak kendisi ekliyor.

Değiştirmeniz gereken tek kısım data-sitekey içerisindeki SITE_ANAHTARINIZ yazan yer. Buraya size verilen site anahtarını yazmanız gerekiyor.

Eski yazıdaki örnek kodda input'un name değeri yoktu. Bir form alanının name değeri yoksa tarayıcı o alanı hiç göndermiyor, yani PHP tarafında yazılan değere ulaşamıyorsunuz. Kendi formunuzda her alana mutlaka bir name verin.

Bir de şunu bilin: Bu yöntemde form, tarayıcının kendi kontrolünden geçmeden gönderiliyor. Yani input'lara required yazsanız bile boş form gidebiliyor. Alanların dolu olup olmadığını PHP tarafında da kontrol edin.

Üçüncü aşama: Back-end

Son aşama olarak doğrulamayı sağlamak için back-end tarafında da bir kontrol yazmamız gerekiyor. Formun gittiği dosyanın adı gonder.php olsun.

PHP
<?php
$secretKey = 'GIZLI_ANAHTARINIZ';

// formla birlikte gelen doğrulama kodu
$token = $_POST['g-recaptcha-response'] ?? '';
if ($token === '') {
    exit('Doğrulama yapılmadı');
}

// kodu Google'a soruyoruz
$istek = stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => 'Content-Type: application/x-www-form-urlencoded',
        'content' => http_build_query([
            'secret'   => $secretKey,
            'response' => $token,
            'remoteip' => $_SERVER['REMOTE_ADDR'],
        ]),
        'timeout' => 10,
    ],
]);
$cevap = file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $istek);
$sonuc = json_decode($cevap, true);

if (empty($sonuc['success'])) {
    exit('Hatalı işlem');
}

// buraya kadar geldiyse gönderen bot değil, formu işleyebiliriz
$ad = htmlspecialchars($_POST['ad'] ?? '', ENT_QUOTES, 'UTF-8');
echo "Başarılı, merhaba $ad";

Değiştirmeniz gereken yer $secretKey içerisindeki GIZLI_ANAHTARINIZ yazan kısım. Buraya size verilen gizli anahtarı yazmanız gerekiyor.

Kod sırasıyla şunları yapıyor:

  1. Formla birlikte gelen doğrulama kodunu alıyor. Kod hiç gelmediyse, yani biri formu reCAPTCHA'dan geçmeden doğrudan bu dosyaya göndermeye çalıştıysa işlemi orada bitiriyor.
  2. Kodu gizli anahtarımızla birlikte Google'a gönderip geçerli mi diye soruyor. Eski kodda gizli anahtar adres satırının içinde gidiyordu, şimdi POST ile gönderiyoruz. Böylece anahtar sunucu loglarına düşmüyor. Google'ın kendi dokümantasyonunda gösterdiği yöntem de bu.
  3. Google "geçerli" dediyse formu işliyor, demediyse "Hatalı işlem" yazıp duruyor. Ad alanını ekrana yazdırmadan önce htmlspecialchars ile temizliyoruz ki biri ad alanına kod yazarak sayfanızda çalıştıramasın.

Kendi sitenizde echo "Başarılı..." yazan yerin yerine formu ne yapmak istiyorsanız onu yazacaksınız, örneğin mail gönderme ya da veritabanına kaydetme.

Sık karşılaşılan hatalar

Doğrulama başarısız olursa Google'ın cevabında sebebi yazıyor. Görmek için deneme yaparken exit('Hatalı işlem'); satırının üstüne geçici olarak var_dump($sonuc); ekleyebilirsiniz. En sık gördüğüm sebepler:

  • invalid-input-secret: Gizli anahtarı yanlış ya da eksik kopyalamışsınız.
  • invalid-input-response: Gelen doğrulama kodu geçersiz. Genelde formu reCAPTCHA'dan geçmeden göndermeye çalışan bir bottan geliyor, yani korumanız işini yapıyor demektir. Kendi denemenizde alıyorsanız site anahtarı ile gizli anahtarın aynı reCAPTCHA kaydına ait olduğundan emin olun.
  • timeout-or-duplicate: Doğrulama kodu sadece bir kere ve 2 dakika içinde kullanılabiliyor. Sayfayı yenilemeden ikinci kez gönderdiyseniz ya da formu uzun süre açık bıraktıysanız bu hatayı alırsınız.
  • Sayfada "Geçersiz alan adı" uyarısı: Sitenizin domainini (ya da deneme yapıyorsanız localhost'u) reCAPTCHA ayarlarındaki alan adlarına eklememişsiniz.

Sağ alttaki rozet

Invisible reCAPTCHA sayfanın sağ alt köşesine küçük bir reCAPTCHA rozeti koyuyor. Tasarımınıza uymuyorsa CSS ile gizleyebilirsiniz:

CSS
.grecaptcha-badge { visibility: hidden; }

Fakat Google rozeti gizlerseniz formun yakınına aşağıdaki gibi bir yazı koymanızı istiyor. Kullanıcıya sitenin reCAPTCHA ile korunduğunu söylemek zorundasınız.

HTML
<small>Bu site reCAPTCHA ile korunmaktadır ve Google
<a href="https://policies.google.com/privacy">Gizlilik Politikası</a> ile
<a href="https://policies.google.com/terms">Hizmet Şartları</a> geçerlidir.</small>

Evet artık reCAPTCHA v2 invisible korumamız aktif oldu. Sitenize yapılan spam mesajların ve form ihlallerinin önüne çok rahatlıkla geçecektir. Umarım anlatım faydalı olmuştur. Eğer kodları bir dosya içerisine derlemekle uğraşmak istemiyorsanız buraya tıklayarak hazır halini indirebilirsiniz. İçinde index.php ve gonder.php dosyaları var, iki anahtarı yazmanız yeterli.

Bu yazıyı paylaşXFacebook