Uygulamanızı Erişim ve Yenileme Tokenları ile Güvenceye Almak: Pratik Bir Rehber
Modern web ve mobil uygulamalar, kullanıcı verilerini korumak ve yetkisiz erişimi engellemek için sağlam güvenlik mekanizmalarına ihtiyaç duyar. Geleneksel oturum yönetimi yöntemleri yerini, özellikle dağıtık sistemlerde ve mikroservis mimarilerinde daha esnek ve ölçeklenebilir olan token tabanlı kimlik doğrulama sistemlerine bırakmaktadır. Bu makale, uygulamanızın güvenliğini artırmak için erişim (access) ve yenileme (refresh) tokenlarının nasıl kullanılacağını, bunların arkasındaki prensipleri ve en iyi uygulama yöntemlerini pratik bir yaklaşımla ele alacaktır.
Uygulama Güvenliğine Giriş ve Geleneksel Yöntemlerin Sınırlılıkları
Uygulama güvenliği, kullanıcı deneyimi kadar kritik bir öneme sahiptir. Kullanıcıların kimliğini doğrulamak ve belirli kaynaklara erişim yetkilerini kontrol etmek, herhangi bir uygulamanın temel güvenlik gereksinimleridir.
Kimlik Doğrulama ve Yetkilendirme Nedir?
Kimlik doğrulama (Authentication), bir kullanıcının veya sistemin iddia ettiği kişi veya sistem olduğunu kanıtlama sürecidir. Genellikle kullanıcı adı ve parola ile yapılır. Yetkilendirme (Authorization) ise, kimliği doğrulanmış bir kullanıcının belirli bir kaynağa veya işleme erişip erişemeyeceğini belirleme sürecidir. Örneğin, bir kullanıcının sadece kendi profiline erişebilmesi veya bir yöneticinin tüm kullanıcıların verilerini görebilmesi yetkilendirme kapsamındadır.
Oturum Tabanlı Kimlik Doğrulama ve Dezavantajları
Geleneksel web uygulamalarında, kullanıcı kimlik doğrulandıktan sonra sunucu tarafında bir oturum (session) oluşturulur. Bu oturuma özel bir oturum kimliği (session ID) kullanıcıya bir çerez (cookie) aracılığıyla gönderilir. Kullanıcı her istek yaptığında bu oturum kimliği sunucuya gönderilir ve sunucu, kullanıcının kimliğini ve yetkilerini bu kimlik üzerinden doğrular.
Bu yaklaşımın bazı dezavantajları şunlardır:
- Ölçeklenebilirlik Sorunları: Sunucu tarafında oturum durumunu saklamak, birden fazla sunucuya sahip dağıtık sistemlerde (load balancer arkasında) oturumların paylaşılmasını veya yapışkan oturumların (sticky sessions) kullanılmasını gerektirir, bu da karmaşıklığı artırır.
- CSRF Riski: Çerez tabanlı oturumlar, Çapraz Site İstek Sahteciliği (CSRF) saldırılarına karşı daha savunmasız olabilir.
- Mobil ve API Odaklı Uygulamalarda Zorluk: Mobil uygulamalar ve stateless (durumsuz) API’ler için çerez tabanlı oturumlar doğal bir çözüm değildir.
Token Tabanlı Yaklaşımın Yükselişi
Token tabanlı kimlik doğrulama, sunucu tarafında oturum durumu tutma ihtiyacını ortadan kaldırır. Kimlik doğrulandıktan sonra, kullanıcıya bir “token” verilir ve bu token, kullanıcının kimliğini ve yetkilerini içerir. Kullanıcı her istek yaptığında bu tokenı sunucuya gönderir. Sunucu, tokenı doğrulayarak isteği işler. Bu yaklaşım, özellikle mikroservis mimarileri ve API odaklı uygulamalar için idealdir.
Erişim Tokenları (Access Tokens) Nedir?
Erişim tokenları, kullanıcının belirli bir süre boyunca belirli kaynaklara erişim yetkisini temsil eden kimlik bilgileridir. Genellikle kısa ömürlüdürler ve doğrudan API çağrılarında kullanılırlar.
Erişim Tokenlarının Yapısı ve İçeriği (JWT)
Günümüzde en yaygın kullanılan erişim tokenı formatı JSON Web Token (JWT)’dır. JWT’ler, üç ana bölümden oluşur: Başlık (Header), Yük (Payload) ve İmza (Signature). Bu bölümler noktalarla ayrılır ve Base64Url ile kodlanır.
HEADER.PAYLOAD.SIGNATURE
Başlık (Header): Tokenın tipini (genellikle JWT) ve kullanılan imzalama algoritmasını (örneğin, HS256 veya RS256) belirtir.
{
"alg": "HS256",
"typ": "JWT"
}
Yük (Payload): "Claim" adı verilen ifadeleri içerir. Bu ifadeler, kullanıcı hakkında bilgiler (örneğin, kullanıcı ID, rol), tokenın geçerlilik süresi (exp), kim tarafından verildiği (iss) gibi verileri taşır.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622, // 1 saat sonra sona erer
"roles": ["admin", "user"]
}
İmza (Signature): Başlık ve yükün Base64Url kodlanmış hallerinin bir sır (secret) veya özel anahtar ile şifrelenmesiyle oluşturulur. Bu imza, tokenın bütünlüğünü ve kimliğini doğrulamak için kullanılır. Tokenın içeriği değiştirilirse imza geçersiz hale gelir.
Erişim Tokenlarının Yaşam Döngüsü
Erişim tokenları genellikle kısa ömürlüdür (örneğin, 5 dakika ila 1 saat). Kullanıcı kimlik doğrulandığında bir erişim tokenı alır. Bu token, belirli bir süre boyunca API isteklerinde kullanılır. Süresi dolduğunda, kullanıcı yeni bir erişim tokenı almak zorundadır.
Erişim Tokenlarının Avantajları ve Riskleri
Avantajları:
- Stateless: Sunucu tarafında oturum durumu tutmaya gerek yoktur, bu da ölçeklenebilirliği artırır.
- Hızlı Doğrulama: Tokenın imzası doğrulandıktan sonra, içindeki bilgiler okunabilir ve hızlı bir şekilde yetkilendirme yapılabilir.
- Çapraz Alan Kullanımı: Farklı alt alan adları veya servisler arasında kolayca paylaşılabilir.
Riskleri:
- Çalınma Riski: Eğer bir erişim tokenı çalınırsa, süresi dolana kadar yetkisiz erişim için kullanılabilir. Kısa ömürlü olmaları bu riski azaltır.
- İptal Zorluğu: Veritabanında bir kayıt tutulmadığı için, süresi dolmadan önce bir erişim tokenını iptal etmek zordur. Blacklist (kara liste) mekanizmaları bu sorunu çözebilir ancak sunucu tarafında durum tutma ihtiyacını geri getirir.
Yenileme Tokenları (Refresh Tokens) Nedir?
Erişim tokenlarının kısa ömürlü olması güvenlik açısından avantajlı olsa da, kullanıcı deneyimini olumsuz etkileyebilir. Her 5-10 dakikada bir yeniden kimlik doğrulaması istemek yerine, yenileme tokenları devreye girer.
Yenileme Tokenlarının Amacı ve Yapısı
Yenileme tokenları, yeni erişim tokenları almak için kullanılan uzun ömürlü tokenlardır. Kullanıcı bir kez kimlik doğrulandıktan sonra, hem bir erişim tokenı hem de bir yenileme tokenı alır. Erişim tokenının süresi dolduğunda, uygulama yenileme tokenını kullanarak sunucudan yeni bir erişim tokenı talep eder. Yenileme tokenları genellikle bir veritabanında saklanır ve sunucu tarafından yönetilir. JWT formatında olabilirler ancak genellikle erişim tokenlarından daha az bilgi içerirler.
Yenileme Tokenlarının Güvenli Saklanması
Yenileme tokenları uzun ömürlü oldukları için, çalınmaları durumunda büyük güvenlik riskleri oluşturabilirler. Bu nedenle, istemci tarafında (tarayıcı veya mobil uygulama) son derece güvenli bir şekilde saklanmaları gerekir:
- Web Uygulamaları için:
HttpOnlyveSecureniteliklerine sahip çerezlerde saklanmalıdır. Bu, JavaScript'in çereze erişmesini engeller (XSS saldırılarına karşı koruma) ve sadece HTTPS üzerinden gönderilmesini sağlar. - Mobil Uygulamalar için: Cihazın güvenli depolama alanlarında (örneğin, iOS Keychain, Android Keystore) saklanmalıdır.
Yenileme Tokenı ile Yeni Erişim Tokenı Alma Süreci
- Kullanıcı, uygulamaya erişim tokenı ile istek gönderir.
- Erişim tokenının süresi dolmuşsa veya geçersizse, sunucu 401 Unauthorized hatası döndürür.
- İstemci, sahip olduğu yenileme tokenını kullanarak sunucuya (genellikle özel bir
/refreshveya/tokenendpoint'ine) yeni bir erişim tokenı talep eder. - Sunucu, yenileme tokenını doğrular (geçerli mi, süresi doldu mu, iptal edildi mi?).
- Eğer yenileme tokenı geçerliyse, sunucu yeni bir erişim tokenı (ve isteğe bağlı olarak yeni bir yenileme tokenı) oluşturup istemciye gönderir.
- İstemci, yeni erişim tokenını kullanarak orijinal isteği tekrar dener.
Erişim ve Yenileme Tokenlarının Birlikte Çalışması
Bu iki token türü, güvenliği ve kullanıcı deneyimini dengelemek için birlikte tasarlanmıştır.
Kimlik Doğrulama Akışı: İlk Giriş
- Kullanıcı, kullanıcı adı ve parola ile kimlik doğrulama sunucusuna istek gönderir.
- Kimlik doğrulama başarılı olursa, sunucu bir erişim tokenı ve bir yenileme tokenı oluşturur.
- Bu tokenlar istemciye gönderilir. Erişim tokenı genellikle bellekte veya
localStorage'da (daha az güvenli) saklanırken, yenileme tokenıHttpOnlyçerezinde veya güvenli depolama alanında saklanır. - İstemci, sonraki API isteklerinde erişim tokenını
Authorizationbaşlığında (Bearer şemasıyla) gönderir.
GET /api/data
Authorization: Bearer [Erişim Tokenı]
Oturumun Sürdürülmesi: Erişim Tokenı Yenileme
Erişim tokenının süresi dolduğunda:
- İstemci, başarısız olan API isteğini yakalar (401 hatası).
- Sakladığı yenileme tokenını kullanarak
/refreshendpoint'ine istek gönderir. - Sunucu, yenileme tokenını doğrular ve yeni bir erişim tokenı (ve muhtemelen yeni bir yenileme tokenı) döndürür.
- İstemci, yeni erişim tokenını saklar ve orijinal isteği bu yeni token ile tekrar dener.
Token İptali ve Oturum Sonlandırma
Kullanıcı çıkış yaptığında veya bir güvenlik ihlali şüphesi olduğunda tokenların iptal edilmesi gerekir.
- Erişim Tokenı İptali: Kısa ömürlü oldukları için, süresi dolana kadar aktif kalırlar. Acil durumlarda, sunucu tarafında bir "blacklist" (kara liste) mekanizması oluşturularak belirli erişim tokenları geçersiz kılınabilir.
- Yenileme Tokenı İptali: Yenileme tokenları uzun ömürlü olduğundan, kullanıcı çıkış yaptığında sunucu tarafındaki veritabanından silinerek veya geçersiz olarak işaretlenerek derhal iptal edilmelidir. Bu, çalınan bir yenileme tokenının yeni erişim tokenları almasını engeller.
Güvenlik En İyi Pratikleri ve Dikkat Edilmesi Gerekenler
Token tabanlı kimlik doğrulama güçlü olsa da, doğru uygulanmadığında güvenlik açıkları oluşturabilir.
Token Saklama Stratejileri (Client-side)
Erişim Tokenı:
- Bellekte (Memory): En güvenli yöntemdir ancak sayfa yenilendiğinde veya kapatıldığında token kaybolur. SPA'lar için uygun olabilir.
localStorageveyasessionStorage: Kolay erişilebilir ancak XSS saldırılarına karşı savunmasızdır. Genellikle önerilmez.
Yenileme Tokenı:
HttpOnlyveSecureÇerezleri: Web uygulamaları için en iyi yöntemdir. JavaScript erişemez, sadece HTTPS üzerinden gönderilir.- Mobil Cihaz Güvenli Depolama: Mobil uygulamalar için (Keychain, Keystore) en iyi yöntemdir.
CSRF ve XSS Saldırılarına Karşı Koruma
- XSS (Cross-Site Scripting): Eğer erişim tokenları
localStorage'da saklanıyorsa, XSS saldırganları bu tokenlara erişebilir.HttpOnlyçerezleri XSS'e karşı koruma sağlar. İçerik Güvenlik Politikası (CSP) uygulamak da XSS riskini azaltır. - CSRF (Cross-Site Request Forgery):
HttpOnlyçerezleri CSRF'ye karşı doğal bir koruma sağlamaz. CSRF tokenları veyaSameSiteçerez niteliği kullanılarak ek koruma sağlanmalıdır. API'ler içinOriginveRefererbaşlıklarını kontrol etmek de faydalıdır.
Token Geçerlilik Süreleri ve Yönetimi
- Erişim Tokenı: Kısa ömürlü olmalıdır (örn. 5-60 dakika). Bu, çalınan bir tokenın kullanım süresini sınırlar.
- Yenileme Tokenı: Daha uzun ömürlü olabilir (örn. 7 gün - 3 ay), ancak yine de bir son kullanma tarihi olmalıdır. Süresi dolduğunda kullanıcının tekrar giriş yapması istenir.
- Token İptali: Kullanıcı çıkış yaptığında veya şüpheli bir etkinlik tespit edildiğinde yenileme tokenları sunucu tarafında derhal iptal edilmelidir.
Yenileme Tokenı Rotasyonu ve Tek Kullanımlık Tokenlar
Her yenileme tokenı kullanıldığında, sunucunun yeni bir yenileme tokenı döndürmesi ve eski tokenı geçersiz kılması (tek kullanımlık yenileme tokenları) güvenliği artırır. Bu, çalınan bir yenileme tokenının sadece bir kez kullanılabilmesini sağlar.
Uygulama Senaryoları ve Geliştirme İpuçları
Erişim ve yenileme tokenlarının farklı uygulama türlerinde nasıl entegre edilebileceğine dair bazı ipuçları.
SPA (Single Page Application) Entegrasyonu
SPA'lar genellikle erişim tokenını bellekte tutar ve yenileme tokenını HttpOnly çerezinde saklar. Bir API isteği 401 döndürdüğünde, bir ara katman (interceptor) yenileme akışını tetikler.
// Örnek bir Axios interceptor (pseudo-code)
axios.interceptors.response.use(
response => response,
async error => {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
const { data } = await axios.post('/refresh-token'); // Yenileme tokenı otomatik çerezden gider
// Yeni erişim tokenını belleğe kaydet
localStorage.setItem('accessToken', data.accessToken);
originalRequest.headers['Authorization'] = 'Bearer ' + data.accessToken;
return axios(originalRequest); // Orijinal isteği tekrar dene
} catch (refreshError) {
// Yenileme tokenı da başarısız oldu, kullanıcıyı çıkış yapmaya zorla
window.location.href = '/login';
return Promise.reject(refreshError);
}
}
return Promise.reject(error);
}
);
Mobil Uygulama Entegrasyonu
Mobil uygulamalar, erişim tokenını da yenileme tokenını da cihazın güvenli depolama alanlarında saklamalıdır. API isteklerinde erişim tokenı Authorization başlığında gönderilir. Yenileme akışı, web'dekiyle benzer şekilde bir hata yakalama mekanizması ile yönetilir.
Sunucu Tarafı (Backend) Uygulamalar
Eğer backend uygulamaları başka bir servise token ile istek yapıyorsa, bu tokenların da güvenli bir şekilde saklanması ve yenilenmesi gerekir. Genellikle bu tür senaryolarda OAuth 2.0 Client Credentials Grant tipi kullanılır veya servisler arası token değişimi yapılır.
Örnek Kod Parçacıkları (Pseudo-code)
Token Alma (Backend):
// Kullanıcı girişi sonrası
POST /login
{ "username": "user", "password": "password" }
// Yanıt:
{
"accessToken": "eyJ...", // Kısa ömürlü
"refreshToken": "xyz...", // Uzun ömürlü
"expiresIn": 3600 // saniye
}
// Yenileme Tokenı ile Yeni Erişim Tokenı Alma (Backend):
POST /refresh-token
// refresh token HttpOnly çerezinden gelir veya body'de gönderilir
// Yanıt:
{
"accessToken": "eyJ...", // Yeni erişim tokenı
"expiresIn": 3600
}
Sonuç
Erişim ve yenileme tokenları, modern uygulama güvenliğinde güçlü ve esnek bir çözüm sunar. Kısa ömürlü erişim tokenları ile anlık API erişimini güvence altına alırken, uzun ömürlü ve güvenli bir şekilde saklanan yenileme tokenları ile kullanıcı oturumlarını kesintisiz ve güvenli bir şekilde sürdürmek mümkündür. Doğru saklama stratejileri, uygun geçerlilik süreleri ve token iptali mekanizmaları ile uygulamanızın güvenlik duruşunu önemli ölçüde güçlendirebilirsiniz. Unutmayın, hiçbir güvenlik çözümü mutlak değildir; sürekli güncel kalmak ve en iyi pratikleri uygulamak hayati önem taşır.
SSS (Sık Sorulan Sorular)
1. Erişim tokenı ve yenileme tokenı arasındaki temel fark nedir?
Erişim tokenı, belirli bir süre boyunca kaynaklara doğrudan erişim yetkisi verir ve genellikle kısa ömürlüdür. Yenileme tokenı ise, erişim tokenının süresi dolduğunda yeni bir erişim tokenı almak için kullanılır ve daha uzun ömürlüdür.
2. Neden erişim tokenları kısa ömürlü olmalıdır?
Erişim tokenları kısa ömürlü olmalıdır çünkü çalınmaları durumunda yetkisiz erişim süresini kısıtlar. Eğer bir token çalınırsa, kısa süre içinde geçersiz hale geleceği için saldırganın faydalanma süresi azalır.
3. Yenileme tokenları nerede saklanmalıdır?
Web uygulamaları için HttpOnly ve Secure niteliklerine sahip çerezlerde saklanmalıdır. Mobil uygulamalar için ise cihazın güvenli depolama alanları (iOS Keychain, Android Keystore) tercih edilmelidir. Bu yöntemler, JavaScript erişimini kısıtlayarak XSS saldırılarına karşı koruma sağlar.
4. JWT kullanmak her zaman güvenli midir?
JWT'ler, tokenın bütünlüğünü imza ile garanti altına alır ancak içerdiği verileri şifrelemez. Hassas bilgiler doğrudan JWT içinde saklanmamalıdır. Ayrıca, JWT'nin imzalanmasında kullanılan sır anahtarın (secret key) güvenliği kritik öneme sahiptir. Eğer sır anahtar açığa çıkarsa, saldırgan geçerli JWT'ler oluşturabilir.
5. Kullanıcı çıkış yaptığında tokenlar nasıl iptal edilir?
Kullanıcı çıkış yaptığında, istemcinin sahip olduğu erişim tokenı (bellekten veya localStorage'dan) ve yenileme tokenı (çerezden veya güvenli depolama alanından) silinmelidir. Ayrıca, yenileme tokenı sunucu tarafında da geçersiz olarak işaretlenmeli veya veritabanından silinmelidir. Erişim tokenları kısa ömürlü oldukları için genellikle süresinin dolması beklenir veya acil durumlarda bir "blacklist" mekanizması kullanılabilir.