Laravel İle Dinamik Bir İki Faktörlü Kimlik Doğrulama Sistemi Nasıl Yapılır?

Laravel İle Dinamik Bir İki Faktörlü Kimlik Doğrulama Sistemi Nasıl Yapılır?
Laravel İle Dinamik Bir İki Faktörlü Kimlik Doğrulama Sistemi Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Uygulamaya başlamadan önce sisteminizde Laravel 11 veya üzeri bir sürümün kurulu olması gerekmektedir. Ayrıca, TOTP protokolünü yönetmek için sektör standardı olan pragmarx/google2fa-laravel paketini kullanacağız. Bu paket, Google Authenticator, Authy veya Microsoft Authenticator gibi uygulamalarla tam uyumludur.

  • PHP 8.2+ sürümü
  • Composer paket yöneticisi
  • Laravel 11+ projesi
  • Redis veya veritabanı tabanlı oturum yönetimi

Paketi projenize dahil etmek için terminalinizde şu komutu çalıştırın:

composer require pragmarx/google2fa-laravel

Bu komut, gerekli kütüphaneleri projenize yükler ve 2FA süreçlerini yönetmeniz için gerekli altyapıyı hazırlar.

Veritabanı Şemasını Hazırlama

Kullanıcıların 2FA durumlarını ve gizli anahtarlarını (secret key) saklamak için users tablosuna yeni sütunlar eklememiz gerekir. Bu anahtar, kullanıcının cihazı ile sunucumuz arasındaki şifreli bağı temsil eder.

// Migration dosyası örneği
Schema::table('users', function (Blueprint $table) {
    $table->text('google2fa_secret')->nullable();
    $table->boolean('is_2fa_enabled')->default(false);
});

Bu sütunlar, kullanıcının 2FA özelliğini aktif edip etmediğini ve doğrulama için gerekli olan gizli anahtarı veritabanında tutmamızı sağlar. Güvenlik nedeniyle google2fa_secret sütununu şifreleyerek saklamanız (encryption) önerilir.

2FA Kurulumu ve QR Kod Oluşturma

Kullanıcı 2FA'yı aktif ettiğinde, ona bir QR kod göstermemiz gerekir. Bu kod, kullanıcının authenticator uygulamasına elle giriş yapmadan hesabı eşleştirmesini sağlar. Aşağıdaki kod bloğu, kullanıcı için dinamik bir gizli anahtar oluşturur ve bunu QR koda dönüştürür.

use PragmaRX\Google2FALaravel\Facade as Google2FA;

public function enableTwoFactor(Request $request)
{
    $user = $request->user();
    $secret = Google2FA::generateSecretKey();
    
    $user->google2fa_secret = encrypt($secret);
    $user->save();

    $QR_Image = Google2FA::getQRCodeInline(
        config('app.name'),
        $user->email,
        $secret
    );

    return view('2fa.enable', ['QR_Image' => $QR_Image]);
}

Burada generateSecretKey metodu, kullanıcıya özel benzersiz bir anahtar üretir. getQRCodeInline ise bu anahtarı bir QR görseline dönüştürerek kullanıcıya sunar.

Doğrulama Mantığını Uygulama

Kullanıcı giriş yaptıktan sonra, eğer 2FA aktifse onu doğrudan panele yönlendirmek yerine doğrulama sayfasına göndermeliyiz. Bunun için bir Middleware oluşturmak en temiz yaklaşımdır. Aşağıdaki örnek, kullanıcının girdiği kodun doğruluğunu kontrol eder.

public function verify2FA(Request $request)
{
    $user = $request->user();
    $secret = decrypt($user->google2fa_secret);
    
    $valid = Google2FA::verifyKey($secret, $request->one_time_password);

    if ($valid) {
        session(['2fa_verified' => true]);
        return redirect()->intended('/dashboard');
    }

    return back()->withErrors(['one_time_password' => 'Geçersiz kod!']);
}

Bu metot, kullanıcının gönderdiği 6 haneli kodu, veritabanındaki şifresi çözülmüş anahtar ile karşılaştırır. Başarılı olursa, oturumda 2FA'nın doğrulandığını belirten bir bayrak (flag) set edilir.

Güvenlik ve Performans Karşılaştırması

2FA yöntemleri arasında seçim yaparken dikkat etmeniz gereken bazı kriterler bulunmaktadır. Aşağıdaki tablo, yaygın yöntemleri karşılaştırmaktadır.

Yöntem Güvenlik Seviyesi Kullanıcı Deneyimi Maliyet
TOTP (Authenticator) Yüksek Orta Ücretsiz
SMS Doğrulama Düşük Yüksek Maliyetli
E-posta Kodu Düşük Orta Ücretsiz
Kritik Güvenlik Uyarısı: Üretim ortamında (production) gizli anahtarları asla düz metin olarak saklamayın. Mutlaka Laravel'in yerleşik encrypt ve decrypt yardımcılarını kullanarak veritabanı seviyesinde şifreleme uygulayın. Ayrıca, 2FA kodlarını deneme yanılma (brute-force) saldırılarına karşı sınırlayan bir "rate limiting" mekanizması kurduğunuzdan emin olun.

Sıkça Sorulan Sorular

2FA kodunu kaybeden kullanıcı ne yapmalı?

Kullanıcılara kurulum aşamasında "Yedek Kodlar" (Recovery Codes) vermelisiniz. Bu kodlar, telefonlarını kaybettiklerinde sisteme giriş yapabilmeleri için tek seferlik kullanılabilen anahtarlardır.

TOTP nedir ve neden güvenlidir?

TOTP (Time-based One-Time Password), zaman tabanlı tek kullanımlık şifreleme algoritmasıdır. Kodlar her 30 saniyede bir değiştiği için, çalınan bir kodun kötü niyetli kişiler tarafından tekrar kullanılması imkansızdır.

Laravel Middleware ile 2FA nasıl zorunlu tutulur?

Oluşturduğunuz 2FA doğrulama middleware'ini, Kernel.php veya bootstrap/app.php dosyasında ilgili rotalara atayarak, doğrulama yapmayan kullanıcıların korumalı sayfalara erişimini engelleyebilirsiniz.

QR kodun güvenliği nasıl sağlanır?

QR kodları sadece HTTPS üzerinden servis edin ve bu sayfaları sadece giriş yapmış, kimliği doğrulanmış kullanıcıların görmesini sağlayın.

Sistem saatleri uyumsuz olursa ne olur?

TOTP protokolü sunucu saati ile cihaz saatine dayanır. Sunucunuzun saat diliminin (NTP üzerinden) doğru olduğundan emin olun, aksi takdirde kullanıcılar hiçbir zaman doğru kodu giremezler.

2FA Sistemlerinde Hata Ayıklama ve Loglama Stratejileri

Dinamik bir 2FA sistemi kurarken karşılaşılan en büyük zorluk, kullanıcıların giriş yapamaması durumunda sorunun kaynağını tespit etmektir. Laravel'in Log facade'ını kullanarak, doğrulama süreçlerindeki hataları izlemek sistemin sürdürülebilirliği için kritiktir.

Aşağıdaki örnekte, başarısız olan 2FA denemelerini kaydeden ve kullanıcıya anlamlı bir hata mesajı dönen bir yapı kurgulayalım:


use Illuminate\Support\Facades\Log;

public function verify(Request $request)
{
    $user = $request->user();
    $code = $request->input('code');

    if (!$this->totpService->verify($user->two_factor_secret, $code)) {
        Log::warning('2FA doğrulama başarısız:', [
            'user_id' => $user->id,
            'ip' => $request->ip(),
            'attempted_at' => now()
        ]);

        return back()->withErrors(['code' => 'Girdiğiniz kod geçersiz veya süresi dolmuş.']);
    }

    return redirect()->intended('/dashboard');
}

Yaygın Hata Senaryoları ve Çözümleri

  • Zaman Senkronizasyon Hataları: Sunucu saati ile istemci (Google Authenticator) saati arasındaki fark 30 saniyeyi geçerse kodlar asla eşleşmez. Sunucunuzda ntp servisinin aktif olduğundan emin olun.
  • Secret Key Şifreleme: Veritabanında sakladığınız two_factor_secret alanını mutlaka encrypt ve decrypt cast özelliklerini kullanarak koruyun.
  • Cache Çakışmaları: Eğer doğrulama sürecinde Redis veya Memcached kullanıyorsanız, anahtarların kullanıcı bazlı (örneğin: 2fa_attempt_{user_id}) olduğundan emin olun.

2FA Süreçleri İçin Otomatik Test Senaryoları

2FA gibi kritik bir güvenlik katmanını manuel test etmek yerine, Laravel'in Pest veya PHPUnit test araçlarını kullanarak otomatize etmelisiniz. Bir kullanıcının 2FA aktifken giriş yapıp yapamadığını test eden örnek bir senaryo:


public function test_user_can_login_with_valid_2fa_code()
{
    $user = User::factory()->create(['two_factor_secret' => 'SECRET_KEY']);

    $response = $this->post('/login', [
        'email' => $user->email,
        'password' => 'password',
    ]);

    $response->assertRedirect('/two-factor-challenge');

    $validCode = $this->totpService->generateCode('SECRET_KEY');

    $this->post('/two-factor-challenge', ['code' => $validCode])
         ->assertRedirect('/dashboard');
}

Test Aşamasında Dikkat Edilmesi Gerekenler

  1. Mocking: TOTP kütüphanesini doğrudan test etmek yerine, başarılı ve başarısız senaryoları simüle eden mock sınıfları kullanın.
  2. İzolasyon: Test veritabanınızda her testten sonra two_factor_secret alanının temizlendiğinden emin olun.
  3. Brute-Force Testi: Sisteminize üst üste hatalı kod girişi yapıldığında, belirli bir süre (örneğin 15 dakika) girişi engelleyen RateLimiter mekanizmasını test edin.

Bu testler, gelecekte yapacağınız kod güncellemelerinde 2FA sisteminizin bozulmadığından emin olmanızı sağlar. Özellikle RateLimiter kullanımı, bot saldırılarına karşı en güçlü savunma hattınızdır.

Sonuç

Laravel ile dinamik bir iki faktörlü kimlik doğrulama sistemi kurmak, kullanıcı verilerini korumak adına atabileceğiniz en etkili adımlardan biridir. Bu rehberde, TOTP protokolünün nasıl entegre edileceğini, veritabanı yönetimi ve doğrulama mantığını öğrendiniz. Bir sonraki adım olarak, kullanıcılarınıza "Yedek Kodlar" oluşturma özelliği ekleyerek sisteminizi daha dayanıklı hale getirebilirsiniz.

Sorumluluk Reddi: Bu makalede yer alan kod örnekleri eğitim amaçlıdır. Uygulamanızın güvenlik mimarisini tasarlarken, projenizin özel ihtiyaçlarını göz önünde bulundurmalı ve profesyonel güvenlik testleri (penetrasyon testleri) yaptırmalısınız. Yazılım güvenliği sürekli güncellenen bir süreçtir.
Bu yazıya tepkinizi paylaşın:
Deniz Aydın

On yıllık deneyimli bir içerik editörü olarak, karmaşık süreçleri herkesin anlayabileceği basit adımlara dönüştürmeyi seviyorum. Okuyucuların hayatını kolaylaştıracak pratik çözümler üretmek temel uzmanlık alanımdır.

Yorumlar (0)

Yorum Yaz