Gereksinimler ve Ön Hazırlık
PHP ile JWT tabanlı bir sistem kurmak için sisteminizde belirli araçların yüklü olması gerekir. JWT işlemleri için tekerleği yeniden icat etmek yerine, sektör standardı olan kütüphaneleri kullanmak en güvenli yoldur.
- PHP 8.2 veya üzeri: Güncel performans ve güvenlik özellikleri için.
- Composer: PHP bağımlılık yönetim aracı.
- firebase/php-jwt: JWT oluşturma ve doğrulama işlemleri için kullanılan en popüler kütüphane.
- PDO (PHP Data Objects): Veritabanı işlemleri için güvenli bir katman.
Projenizin kök dizininde terminali açarak gerekli kütüphaneyi şu komutla yükleyebilirsiniz:
composer require firebase/php-jwt
JWT Nedir ve Neden Kullanılır?
JWT, taraflar arasında bilgileri bir JSON nesnesi olarak güvenli bir şekilde iletmek için kullanılan açık bir standarttır (RFC 7519). Kimlik doğrulama sürecinde, kullanıcı giriş yaptığında sunucu bir token üretir ve bunu istemciye gönderir. İstemci, sonraki her istekte bu tokenı Authorization: Bearer başlığında sunucuya iletir.
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Session (Oturum) | Sunucu tarafında kontrol kolaydır. | Ölçeklenmesi zordur (Sticky session gerektirir). |
| JWT | Durumsuzdur, ölçeklenebilir. | Token iptali (revocation) daha karmaşıktır. |
Adım Adım JWT Token Oluşturma
Kullanıcı başarıyla giriş yaptığında (kullanıcı adı ve şifre doğrulanmışsa), sunucumuz bir JWT üretmelidir. Bu işlemde gizli bir anahtar (secret key) kullanılır. Bu anahtarın asla paylaşılmaması gerekir.
Yukarıdaki kod, kullanıcıya 1 saat geçerli bir token üretir. 'iss' (issuer), 'iat' (issued at) ve 'exp' (expiration) gibi standart claim'lerin kullanılması, tokenın güvenliğini ve izlenebilirliğini artırır.
Gelen İsteklerin Doğrulanması
İstemci, API'nin korumalı bir rotasına istek attığında, sunucu gelen tokenı doğrulamalıdır. Eğer token geçerliyse, kullanıcıya veri döndürülür; aksi takdirde 401 Unauthorized hatası verilir.
Bu kod bloğu, Authorization başlığını kontrol eder, tokenı çözer ve imzasını doğrular. İmza doğrulanmazsa veya süre dolmuşsa Exception fırlatılır.
Güvenlik Önlemleri ve En İyi Pratikler
Kritik Uyarı: Gizli anahtarınızı (secret key) asla kaynak kodunuzun içine yazmayın. Üretim ortamlarında (production) mutlaka .env dosyaları veya güvenli bir kasa (Vault) kullanın. Ayrıca, HTTPS kullanmadan JWT iletimi yapmak, tokenın araya giren kişiler tarafından çalınmasına neden olur.
JWT kullanırken dikkat edilmesi gereken bir diğer nokta ise şifreleme algoritmasıdır. Her zaman HS256 veya daha güçlü bir algoritma tercih edin. Asla 'none' algoritmasına izin vermeyin.
Veritabanı ile Entegrasyon
JWT içindeki kullanıcı ID'sini kullanarak veritabanından kullanıcı bilgilerini çekmek en yaygın senaryodur. SQL Injection riskine karşı her zaman prepared statements kullanmalısınız.
Bu yöntem, token içindeki 'sub' değerini kullanarak veritabanına sorgu atar. Kullanıcıyı doğrulamak için veritabanı sorgusunun sonucunu kullanmak, yetkilendirme (authorization) katmanının temelidir.
Sıkça Sorulan Sorular
JWT süresi dolduğunda ne yapmalıyım?
Token süresi dolduğunda istemciye 401 hatası dönülür. İstemci, elindeki "Refresh Token"ı kullanarak yeni bir erişim tokenı talep etmelidir.
JWT'leri veritabanında saklamalı mıyım?
Hayır, JWT'lerin temel amacı durumsuz (stateless) olmalarıdır. Ancak, güvenlik gereği token iptali (logout) yapmanız gerekiyorsa, geçersiz kılınan tokenları bir kara listeye (blacklist) alabilirsiniz.
Tokenı nerede saklamalıyım?
Web tarayıcılarında HttpOnly ve Secure flag'lerine sahip çerezlerde (cookie) saklamak, XSS saldırılarına karşı en güvenli yöntemdir.
Hangi algoritmayı kullanmalıyım?
Basit ve hızlı işlemler için HS256 yeterlidir. Daha yüksek güvenlik gerektiren sistemlerde asimetrik şifreleme sağlayan RS256 (Public/Private key) tercih edilmelidir.
JWT'nin içine hassas veri koyabilir miyim?
Hayır, JWT içeriği herkes tarafından okunabilir (base64 kodludur). Şifre veya kişisel verileri asla token içine eklemeyin.
JWT Uygulamalarında Hata Ayıklama ve Loglama Stratejileri
JWT tabanlı sistemlerde hata ayıklama süreci, token'ın yapısı gereği bazen karmaşık olabilir. Bir istek reddedildiğinde, sorunun token'ın süresinin dolmasından mı, imza uyuşmazlığından mı yoksa yanlış yapılandırılmış bir header'dan mı kaynaklandığını hızlıca tespit etmeniz gerekir. Profesyonel bir API geliştirme sürecinde, her doğrulama aşamasını loglamak kritik öneme sahiptir.
Aşağıdaki örnek, JWT doğrulama sürecinde oluşabilecek hataları yakalayıp, geliştirici için anlamlı hata mesajları döndüren bir yapı sunar:
try {
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
} catch (ExpiredException $e) {
// Token süresi dolmuş
error_log("Token Süresi Doldu: " . $e->getMessage());
http_response_code(401);
echo json_encode(["error" => "Token süresi dolmuştur, lütfen giriş yapın."]);
} catch (SignatureInvalidException $e) {
// İmza geçersiz (Manipülasyon girişimi olabilir)
error_log("Geçersiz İmza Girişimi: " . $e->getMessage());
http_response_code(403);
echo json_encode(["error" => "Geçersiz imza."]);
} catch (Exception $e) {
// Genel hata durumu
error_log("JWT Hatası: " . $e->getMessage());
http_response_code(400);
echo json_encode(["error" => "Doğrulama başarısız."]);
}
Performans Optimizasyonu: Token Doğrulama Yükünü Hafifletmek
Her API isteğinde veritabanına giderek kullanıcının aktif olup olmadığını kontrol etmek, yüksek trafikli uygulamalarda darboğaz oluşturabilir. Performansı artırmak için şu stratejileri izleyebilirsiniz:
- Redis Kullanımı: Kullanıcı yetkilerini veya "blacklist"e alınan token'ları veritabanı yerine Redis gibi bir bellek içi (in-memory) veri deposunda tutun.
- Token Önbellekleme: Doğrulanan token'ları kısa süreliğine önbelleğe alarak, aynı token ile gelen ardışık isteklerde imza kontrolünü minimize edin.
- Payload Boyutunu Kısıtlayın: JWT içerisine sadece gerekli olan
sub(ID) verolegibi verileri ekleyin. Token boyutu ne kadar küçük olursa, ağ üzerindeki yük o kadar az olur.
Test Odaklı Geliştirme (TDD) ile JWT Doğrulaması
API güvenliğinizi garanti altına almanın en iyi yolu, birim testleri (unit tests) yazmaktır. PHPUnit kullanarak, farklı senaryoları (geçerli token, süresi dolmuş token, sahte imza) simüle edebilirsiniz.
Aşağıdaki test örneği, sisteminizin token doğrulama mantığını nasıl test edeceğinizi gösterir:
public function testExpiredTokenReturnsUnauthorized()
{
$expiredToken = $this->generateToken(['exp' => time() - 3600]);
$response = $this->apiCall('/api/resource', 'GET', $expiredToken);
$this->assertEquals(401, $response->getStatusCode());
$this->assertStringContainsString('süresi dolmuştur', $response->getBody());
}
Bu yaklaşım, kodunuzda yapacağınız bir değişiklikte güvenlik mekanizmasının bozulup bozulmadığını anında anlamanızı sağlar. Özellikle CI/CD süreçlerinde, her deploy öncesi bu testlerin otomatik olarak çalıştırılması, canlı ortamda oluşabilecek güvenlik açıklarını büyük oranda engeller.
Sonuç
PHP ile JWT tabanlı kimlik doğrulama, modern API mimarilerinin vazgeçilmez bir parçasıdır. Bu rehberde, token oluşturma, doğrulama ve güvenli veritabanı sorgulama adımlarını öğrendiniz. Bir sonraki adım olarak, "Refresh Token" mekanizmasını ve token kara listeleme (blacklist) sistemlerini araştırarak uygulamanızın güvenliğini bir üst seviyeye taşıyabilirsiniz.
Yasal Sorumluluk Reddi: Bu makalede yer alan kod örnekleri eğitim amaçlıdır. Uygulamalarınızın güvenliğinden ve verilerin korunmasından geliştirici olarak siz sorumlusunuz. Üretim ortamına geçmeden önce mutlaka kapsamlı güvenlik testleri yapın.


Yorumlar (0)
Yorum Yaz