Teknoloji, Bilim ve Akıl
Web Sitesine Google ile Giriş Nasıl Eklenir? PHP Rehberi
Web Programlama

Web Sitesine Google ile Giriş Nasıl Eklenir? PHP Rehberi

7 dk okuma 2 okunma 0 yorum
İçindekiler
  1. Kısa Özet
  2. Google ile giriş nedir?
  3. Google ile giriş nasıl çalışır?
  4. Hangi yöntemi seçmeliyim?
  5. Google Cloud Console ayarları nasıl yapılır?
  6. Google giriş butonu sayfaya nasıl eklenir?
  7. Kullanıcı tablosu nasıl olmalı?
  8. ID token PHP ile nasıl doğrulanır?
  9. Yoğun trafikli sitelerde hangi yöntem daha iyi?
  10. Güvenlik başlıkları ve CSP nasıl ayarlanır?
  11. Güvenlik kontrol listesi
  12. En sık karşılaşılan hatalar ve çözümleri
  13. KVKK ve gizlilik politikasında nelere dikkat edilmeli?
  14. Sıkça Sorulan Sorular
  15. Google ile giriş ücretli mi?
  16. Client Secret değerine ihtiyacım var mı?
  17. Kullanıcıyı e-posta ile mi yoksa sub ile mi tanımlamalıyım?
  18. Google ile giriş Safari ve Firefox tarayıcılarında çalışır mı?
  19. Mevcut şifreli üyelik sistemimi bozmadan ekleyebilir miyim?
  20. Alt klasörde çalışan bir sitede ne değişir?

Web sitesine Google ile giriş eklemek için üç adım yeterlidir: Google Cloud Console üzerinden bir OAuth istemci kimliği (Client ID) oluşturursunuz, sayfanıza Google Identity Services (GIS) butonunu yerleştirirsiniz ve butondan gelen kimlik jetonunu (ID token) sunucu tarafında PHP ile doğrulayıp kullanıcıyı oturuma alırsınız. Şifre saklamanıza, e-posta doğrulama kodu göndermenize gerek kalmaz; kullanıcı tek tıkla kayıt olur.

Bu rehberde teknikzeka.net üzerinde kendi PHP ve SQLite projelerimizde kullandığımız yapıyı anlatıyoruz. Kodlar framework gerektirmez, paylaşımlı hostingde de çalışır.

Kısa Özet

  • Gereken: Google hesabı, HTTPS çalışan bir site, PHP 8.0 ve üzeri, cURL eklentisi.
  • Kullanılan teknoloji: Google Identity Services (GIS) kütüphanesi ve OpenID Connect ID token.
  • En kritik kural: Tarayıcıdan gelen jetona asla doğrudan güvenmeyin; sunucuda aud, iss, exp ve email_verified alanlarını kontrol edin.
  • Kullanıcıyı tanımlayan alan: E-posta değil, Google tarafından verilen değişmez sub kimliğidir.
  • Süre: Hazırlık dahil yaklaşık 30-45 dakika.

Google ile giriş nedir?

Google ile giriş (Sign in with Google), kullanıcının sitenize ayrı bir şifre oluşturmadan Google hesabıyla kimliğini kanıtlamasını sağlayan bir oturum açma yöntemidir. Arka planda OAuth 2.0 ve OpenID Connect standartları çalışır. Google, kullanıcının kim olduğunu imzalı bir jetonla sitenize bildirir; siz de bu jetonu doğrulayıp kullanıcıyı içeri alırsınız.

Bu yöntemin site sahibi için en büyük faydası şifre yönetimi yükünün ortadan kalkmasıdır. Şifre sıfırlama e-postaları, sızdırılmış şifre riski ve sahte e-posta ile açılan hesaplar büyük ölçüde azalır. Google tarafında doğrulanmış e-posta adresi gelir.

Google ile giriş nasıl çalışır?

Akış dört adımdan oluşur:

  1. Kullanıcı sitenizdeki Google butonuna tıklar.
  2. Tarayıcıda Google hesap seçim penceresi açılır, kullanıcı hesabını seçer.
  3. Google, JavaScript geri çağırma (callback) fonksiyonunuza credential adında bir ID token (JWT) gönderir.
  4. Bu jetonu sunucunuza POST edersiniz, PHP tarafında doğrulanır ve kullanıcı oturumu başlatılır.

Güncel Chrome sürümlerinde hesap seçim penceresi FedCM (Federated Credential Management) adlı tarayıcı API aracı üzerinden açılır. Bu, üçüncü taraf çerezlere ihtiyaç duymadan giriş yapılmasını sağlar. Yeni kurulumlarda ek bir ayar yapmanıza gerek yoktur; GIS kütüphanesi bunu kendisi yönetir.

Hangi yöntemi seçmeliyim?

Google ile giriş için iki temel yöntem vardır. Çoğu blog, üyelik sitesi ve küçük SaaS projesi için birinci yöntem yeterlidir.

Özellik GIS Butonu (ID Token) OAuth Yönlendirme (Authorization Code)
Amaç Sadece kimlik doğrulama Kimlik + Google verilerine erişim (Drive, Takvim vb.)
Kurulum zorluğu Kolay Orta
Sayfa yönlendirmesi Yok, açılır pencere Google sayfasına gidip geri döner
Gereken ayar Yetkili JavaScript kaynakları Yetkili yönlendirme URI adresleri
One Tap desteği Var Yok
Önerilen kullanım Üyelik, yorum, panel girişi Kullanıcı adına Google servisi kullanılacaksa

Bu makalede birinci yöntemi, yani GIS butonu ve ID token doğrulamasını anlatıyoruz.

Google Cloud Console ayarları nasıl yapılır?

Kod yazmadan önce Google tarafında bir istemci kimliği almanız gerekir. Adımlar şöyledir:

  1. console.cloud.google.com adresine gidin ve yeni bir proje oluşturun. Proje adını site adınız yapmanız takibi kolaylaştırır.
  2. Sol menüden Google Auth Platform (eski adıyla OAuth izin ekranı) bölümüne girin.
  3. Markalama (Branding) kısmında uygulama adını, destek e-postasını, site adresini, gizlilik politikası ve kullanım koşulları bağlantılarını doldurun.
  4. Hedef kitle (Audience) kısmında kullanıcı türünü Harici (External) seçin.
  5. İstemciler (Clients) bölümünden yeni istemci oluşturun, uygulama türü olarak Web uygulaması seçin.
  6. Yetkili JavaScript kaynakları alanına sitenizin adresini ekleyin. Örnek: https://www.siteniz.com ve https://siteniz.com. Sonuna eğik çizgi veya klasör yolu koymayın.
  7. Yerel geliştirme yapacaksanız hem http://localhost hem de http://localhost:8000 gibi port içeren adresi ayrı ayrı ekleyin.
  8. Oluşturulan İstemci Kimliği değerini kopyalayın. xxxx.apps.googleusercontent.com şeklinde biter.

Önemli not: Uygulama Test durumundayken yalnızca test kullanıcısı olarak eklediğiniz hesaplar giriş yapabilir. Herkesin kullanabilmesi için Hedef kitle ekranından uygulamayı Yayınla (In production) durumuna almanız gerekir. Sadece openid, email ve profile bilgisi kullanıldığında uzun bir inceleme süreci beklenmez.

Google giriş butonu sayfaya nasıl eklenir?

Giriş sayfanızın HTML kısmına aşağıdaki kodu ekleyin. data-client_id değerine kendi istemci kimliğinizi yazın.

<meta name="csrf-token" content="<?= htmlspecialchars($_SESSION['csrf']) ?>">
<script src="https://accounts.google.com/gsi/client" async></script>

<div id="g_id_onload"
     data-client_id="XXXX.apps.googleusercontent.com"
     data-callback="googleGirisSonucu"
     data-auto_prompt="false">
</div>

<div class="g_id_signin"
     data-type="standard"
     data-theme="outline"
     data-size="large"
     data-text="signin_with"
     data-shape="rectangular"
     data-locale="tr">
</div>

<script>
function googleGirisSonucu(yanit) {
  const veri = new FormData();
  veri.append('credential', yanit.credential);
  veri.append('csrf', document.querySelector('meta[name="csrf-token"]').content);

  fetch('google-giris.php', { method: 'POST', body: veri })
    .then(r => r.json())
    .then(s => {
      if (s.ok) { window.location.href = s.yonlendir; }
      else { alert(s.hata); }
    })
    .catch(() => alert('Bağlantı hatası, lütfen tekrar deneyin.'));
}
</script>

data-auto_prompt="false" değeri One Tap penceresinin sayfa açılır açılmaz kendiliğinden çıkmasını engeller. Ziyaretçiyi rahatsız etmeden sadece butonla giriş istiyorsanız bu ayar doğrudur. One Tap kullanmak isterseniz değeri true yapmanız yeterlidir.

CSRF jetonu için oturum başlatılan dosyada şu satırı kullanabilirsiniz: $_SESSION['csrf'] ??= bin2hex(random_bytes(32));

Kullanıcı tablosu nasıl olmalı?

SQLite kullanan projelerde kullanıcı tablosuna Google kimliğini tutacak bir sütun eklemek yeterlidir. Klasik şifreli giriş de kullanılacaksa sifre_hash sütunu boş bırakılabilir.

CREATE TABLE IF NOT EXISTS kullanicilar (
  id          INTEGER PRIMARY KEY AUTOINCREMENT,
  eposta      TEXT UNIQUE NOT NULL,
  ad          TEXT,
  foto        TEXT,
  sifre_hash  TEXT,
  google_sub  TEXT UNIQUE,
  olusturma   TEXT DEFAULT CURRENT_TIMESTAMP,
  son_giris   TEXT
);

google_sub alanı Google hesabının değişmez kimliğidir. Kullanıcı Gmail adresini değiştirse bile bu değer aynı kalır. Bu yüzden eşleştirmede birincil anahtar olarak e-posta değil bu alan kullanılmalıdır.

ID token PHP ile nasıl doğrulanır?

Sunucuya gelen jeton doğrulanmadan hiçbir işlem yapılmamalıdır. Aşağıdaki google-giris.php dosyası ek kütüphane gerektirmez; Google tokeninfo uç noktasını kullanarak jetonu doğrular, kullanıcıyı bulur veya oluşturur ve oturumu başlatır.

<?php
// google-giris.php
session_start();
header('Content-Type: application/json; charset=utf-8');

const GOOGLE_CLIENT_ID = 'XXXX.apps.googleusercontent.com';

function cevap(bool $ok, string $mesaj = '', string $yonlendir = ''): void {
    http_response_code($ok ? 200 : 401);
    echo json_encode(['ok' => $ok, 'hata' => $mesaj, 'yonlendir' => $yonlendir]);
    exit;
}

// 1) CSRF kontrolü
if (!hash_equals($_SESSION['csrf'] ?? '', $_POST['csrf'] ?? '')) {
    cevap(false, 'Güvenlik doğrulaması başarısız.');
}

// 2) Jetonu al
$credential = $_POST['credential'] ?? '';
if ($credential === '') {
    cevap(false, 'Google jetonu alınamadı.');
}

// 3) Google ile doğrula
$ch = curl_init('https://oauth2.googleapis.com/tokeninfo?id_token=' . urlencode($credential));
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10]);
$yanit = curl_exec($ch);
$kod   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$veri = json_decode((string) $yanit, true);
if ($kod !== 200 || !is_array($veri)) {
    cevap(false, 'Jeton doğrulanamadı.');
}

// 4) Alan kontrolleri
$issOk   = in_array($veri['iss'] ?? '', ['accounts.google.com', 'https://accounts.google.com'], true);
$audOk   = ($veri['aud'] ?? '') === GOOGLE_CLIENT_ID;
$expOk   = (int) ($veri['exp'] ?? 0) > time();
$emailOk = ($veri['email_verified'] ?? '') === 'true';

if (!$issOk || !$audOk || !$expOk || !$emailOk) {
    cevap(false, 'Geçersiz Google hesabı bilgisi.');
}

$sub   = $veri['sub'];
$eposta = strtolower($veri['email']);
$ad    = $veri['name'] ?? '';
$foto  = $veri['picture'] ?? '';

// 5) Veritabanı işlemleri
$db = new PDO('sqlite:' . __DIR__ . '/veri/site.db');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$s = $db->prepare('SELECT id FROM kullanicilar WHERE google_sub = ?');
$s->execute([$sub]);
$id = $s->fetchColumn();

if (!$id) {
    // Aynı e-posta ile daha önce açılmış hesap varsa bağla
    $s = $db->prepare('SELECT id FROM kullanicilar WHERE eposta = ?');
    $s->execute([$eposta]);
    $id = $s->fetchColumn();

    if ($id) {
        $db->prepare('UPDATE kullanicilar SET google_sub = ? WHERE id = ?')->execute([$sub, $id]);
    } else {
        $db->prepare('INSERT INTO kullanicilar (eposta, ad, foto, google_sub) VALUES (?, ?, ?, ?)')
           ->execute([$eposta, $ad, $foto, $sub]);
        $id = $db->lastInsertId();
    }
}

$db->prepare("UPDATE kullanicilar SET son_giris = datetime('now') WHERE id = ?")->execute([$id]);

// 6) Oturumu başlat
session_regenerate_id(true);
$_SESSION['kullanici_id'] = (int) $id;

cevap(true, '', 'hesabim.php');

Yoğun trafikli sitelerde hangi yöntem daha iyi?

Tokeninfo uç noktası her girişte Google sunucusuna bir istek atar. Günde birkaç yüz giriş alan sitelerde bu sorun değildir. Trafik yüksekse jeton imzasını yerelde doğrulayan resmi kütüphaneyi kullanmak daha hızlıdır:

// composer require google/apiclient
$client  = new Google\Client(['client_id' => GOOGLE_CLIENT_ID]);
$payload = $client->verifyIdToken($credential);

if ($payload === false) {
    cevap(false, 'Jeton doğrulanamadı.');
}
// $payload['sub'], $payload['email'] ve diğer alanlar kullanılabilir

Bu yöntemde Google genel anahtarları önbelleğe alınır, imza, aud, iss ve exp kontrolleri kütüphane içinde yapılır. email_verified kontrolünü yine kendiniz eklemelisiniz.

Güvenlik başlıkları ve CSP nasıl ayarlanır?

Sitenizde Content Security Policy (CSP) tanımlıysa Google butonu görünmeyebilir veya pencere açılmayabilir. .htaccess dosyasındaki CSP satırına Google adreslerini eklemeniz gerekir:

<IfModule mod_headers.c>
  Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://accounts.google.com/gsi/client; frame-src https://accounts.google.com/gsi/; connect-src 'self' https://accounts.google.com/gsi/; style-src 'self' 'unsafe-inline' https://accounts.google.com/gsi/style; img-src 'self' data: https://lh3.googleusercontent.com"
  Header always set Cross-Origin-Opener-Policy "same-origin-allow-popups"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>

Tailwind CDN, analiz kodları veya reklam ağı kullanıyorsanız onların adreslerini de aynı satıra eklemeyi unutmayın. lh3.googleusercontent.com adresi kullanıcının profil fotoğrafını göstermek için gereklidir. Cross-Origin-Opener-Policy değeri same-origin olarak ayarlanırsa açılır pencere sonucu sayfaya geri dönemez.

Güvenlik kontrol listesi

  • Jeton sunucuda doğrulanmalı: JavaScript tarafında çözülen bilgilere asla güvenmeyin.
  • aud kontrolü şart: Başka bir sitenin istemci kimliğiyle alınmış jetonlar bu kontrol olmadan kabul edilebilir.
  • Doğrulanmamış e-posta reddedilmeli: email_verified değeri true değilse hesap eşleştirmesi yapmayın.
  • Oturum kimliği yenilenmeli: Girişten sonra session_regenerate_id(true) çağrısı oturum sabitleme saldırısını önler.
  • Oturum çerezi güvenli olmalı: session.cookie_secure, httponly ve samesite=Lax ayarlarını açın.
  • İstemci kimliği gizli değildir: Client ID sayfada görünür, sorun değildir. Ancak Client Secret değeri bu yöntemde hiç kullanılmaz ve hiçbir yerde paylaşılmamalıdır.
  • HTTPS zorunlu: Canlı sitede yetkili kaynaklar yalnızca HTTPS olarak tanımlanabilir.

En sık karşılaşılan hatalar ve çözümleri

Kendi projelerimizde kurulum sırasında karşılaştığımız hataların büyük kısmı kod değil ayar kaynaklıdır:

Hata Sebep Çözüm
The given origin is not allowed for the given client ID Site adresi yetkili JavaScript kaynaklarında yok www ve www olmayan iki adresi de ekleyin, değişikliğin yayılması için birkaç dakika bekleyin
Buton hiç görünmüyor CSP veya reklam engelleyici gsi/client dosyasını engelliyor Tarayıcı konsolunu kontrol edin, CSP satırını güncelleyin
Sunucu 401 dönüyor PHP dosyasındaki istemci kimliği ile HTML tarafındaki farklı Her iki yerde aynı Client ID değerini kullanın
Sadece benim hesabım giriş yapabiliyor Uygulama Test durumunda Hedef kitle ekranından uygulamayı yayına alın
Localhost üzerinde çalışmıyor Port numaralı adres eklenmemiş Hem http://localhost hem de port içeren adresi ekleyin
One Tap penceresi çıkmıyor Kullanıcı daha önce kapatmış, bekleme süresi devrede Normaldir, kalıcı buton her zaman sayfada bulunmalı
Kodu içeren yazı kaydederken 403 hatası Sunucu güvenlik duvarı (ModSecurity) kod parçalarını saldırı sanıyor Kod bloklarını HTML kodlanmış olarak kaydedin veya ilgili kuralı panel yolu için muaf tutun

KVKK ve gizlilik politikasında nelere dikkat edilmeli?

Google ile giriş kullandığınızda kullanıcının adı, e-posta adresi ve profil fotoğrafı sitenize aktarılır. Bu verilerin hangi amaçla işlendiği gizlilik politikanızda açıkça yazmalıdır. Google Cloud Console markalama ekranına eklediğiniz gizlilik politikası bağlantısı da çalışır durumda olmalıdır.

Kullanıcıya hesabını silme imkanı sunmanız hem KVKK hem de Google politikaları açısından önemlidir. Hesap silindiğinde google_sub dahil tüm kayıtların kaldırılması gerekir.

Sıkça Sorulan Sorular

Google ile giriş ücretli mi?

Hayır. Google Identity Services ile kimlik doğrulama ücretsizdir. Google Cloud projesi oluşturmak için faturalandırma hesabı bağlamanız da gerekmez.

Client Secret değerine ihtiyacım var mı?

GIS butonu ve ID token yöntemi kullanılıyorsa hayır. Client Secret yalnızca sunucu tarafında yetkilendirme kodu alınan OAuth yönlendirme akışında gerekir.

Kullanıcıyı e-posta ile mi yoksa sub ile mi tanımlamalıyım?

Kalıcı eşleştirme için sub değerini kullanın. E-posta adresi değişebilir, sub değeri ise aynı Google hesabı için her zaman sabittir. E-posta yalnızca ilk girişte mevcut hesapla bağlantı kurmak için kullanılmalıdır.

Google ile giriş Safari ve Firefox tarayıcılarında çalışır mı?

Evet. FedCM desteklemeyen tarayıcılarda GIS kütüphanesi otomatik olarak açılır pencere yöntemine geçer. Kullanıcı tarafında ek bir işlem gerekmez.

Mevcut şifreli üyelik sistemimi bozmadan ekleyebilir miyim?

Evet. Kullanıcı tablosuna google_sub sütunu eklemeniz yeterlidir. Aynı doğrulanmış e-posta ile gelen kullanıcı mevcut hesabına bağlanır, şifreyle girişe de devam edebilir.

Alt klasörde çalışan bir sitede ne değişir?

Hiçbir şey değişmez. Yetkili JavaScript kaynakları alanına yalnızca alan adı yazılır, klasör yolu yazılmaz. PHP tarafında yönlendirme adreslerini BASE_URL ile dinamik üretmeniz yeterlidir.

Ramazan Yeşildal
Ramazan Yeşildal

Karaman merkezli bilgi teknolojileri yöneticisi ve bağımsız yazılım geliştirici.

0 Yorum

Yorum yazın

E-posta adresiniz yayınlanmaz. Yorumlar onaydan sonra görünür.