Blog Projeler Dokümanlar Araçlar Hizmetler Dosyalar Linkler Hakkımda İletişim
.NET, API, veritabanı ve kullanıcı arayüzü bileşenlerinden oluşan yazılım mimarisi

Refresh Token Nedir? JWT Access ve Refresh Token Akışı

Access ve refresh token farkını; rotation, reuse detection, güvenli saklama, iptal ve ASP.NET Core uygulama akışıyla açıklayan teknik rehber.

Refresh token nedir?

Refresh token, kısa ömürlü access token sona erdiğinde kullanıcıyı yeniden girişe zorlamadan yeni bir access token alınmasını sağlayan uzun ömürlü kimlik bilgisidir. Access token API isteğinde taşınır; refresh token ise yalnız token yenileme uç noktasına gönderilir. Bu ayrım, ele geçirilen bir access tokenın kullanılabileceği süreyi kısaltır.

Refresh token bir “sonsuz oturum anahtarı” değildir. TLS ile taşınmalı, istemci ve yetki kapsamına bağlanmalı, tahmin edilemez olmalı, sunucu tarafında iptal edilebilmeli ve hareketsizlik sonunda sona ermelidir. Public client için RFC 9700, tokenı gönderen istemciye kriptografik olarak bağlamayı veya her yenilemede refresh token rotation uygulamayı zorunlu güvenlik seçenekleri olarak tanımlar.

Access token ile refresh token arasındaki fark

Özellik Access token Refresh token
Amaç API kaynağına erişim Yeni access token alma
Gönderildiği yer Korunan API endpointleri Yalnız token endpointi
Ömür Kısa Daha uzun, politikaya bağlı
İçerik JWT veya opaque olabilir Opaque ya da bütünlüğü korunan yapı olabilir
Sunucu kaydı Her tasarımda zorunlu değil İptal, rotation ve reuse detection için gerekir
Ele geçirilme etkisi Süresi ve kapsamıyla sınırlı Yeni access token üretebildiği için daha kritiktir

Access tokenın kısa tutulması tek başına yeterli değildir. Audience, issuer, imza, süre, kullanıcı durumu, oturum ve yetki sürümü her istekte doğrulanmalıdır.

JWT refresh token mıdır?

JWT bir veri biçimidir; refresh tokenın görevi değildir. Access token JWT olabilir. Refresh token da JWT olarak üretilebilir, ancak zorunlu değildir. Uygulama içi oturum yenilemede rastgele üretilmiş opaque token kullanmak, token içeriğini istemciye açıklamadan sunucuda hash, family ve iptal durumu tutmayı kolaylaştırır.

Bu projede refresh token kriptografik rastgele üretilir ve veritabanında açık değer yerine hash saklanır. İstemcinin sunduğu değer tekrar hashlenerek kayıt aranır.

Güvenli yenileme akışı

  1. Kullanıcı doğrulandıktan sonra kısa ömürlü access token ve rastgele refresh token üret.
  2. Refresh tokenın yalnız hashini; kullanıcı, session, family, expiry ve güvenlik sürümüyle kaydet.
  3. Yenileme isteğinde tokenı hashle ve kaydı transaction içinde kilitle.
  4. Kayıt yoksa, süresi dolmuşsa, kullanıcı pasifse veya yetki sürümü değişmişse isteği reddet.
  5. Kullanılmış ya da iptal edilmiş token tekrar geldiyse token ailesini iptal et.
  6. Geçerli tokenı iptal edilmiş olarak işaretle ve yerine yeni refresh token kaydı ekle.
  7. Transaction başarıyla tamamlandıktan sonra yeni access + refresh token çiftini dön.

Tek kullanımlık davranış eşzamanlı iki yenileme isteğinde de korunmalıdır. HDYBlog API bu nedenle mevcut tokenı Serializable transaction ve UPDLOCK, ROWLOCK ile okur; eski kaydı iptal etme ve yeni kaydı ekleme aynı transaction içinde yapılır.

ASP.NET Core rotation iskeleti

Aşağıdaki parça projenin çalışan AuthService.RefreshTokenAsync akışının sadeleştirilmiş iskeletidir. Token değeri SQL metnine eklenmez; Dapper parametresi olarak taşınır.

var tokenHash = tokenService.HashRefreshToken(refreshToken);

await using var connection = await connectionFactory.CreateConnectionAsync(ct);
await using var transaction = await connection.BeginTransactionAsync(
    IsolationLevel.Serializable, ct);

var current = await connection.QueryFirstOrDefaultAsync<RefreshToken>(
    new CommandDefinition(
        """
        SELECT TOP (1) rt.*
        FROM dbo.RefreshTokens rt WITH (UPDLOCK, ROWLOCK)
        WHERE rt.TokenHash = @TokenHash
          AND rt.DeletedAt IS NULL;
        """,
        new { TokenHash = tokenHash }, transaction, cancellationToken: ct));

if (current is null)
    return null;

if (current.RevokedAt is not null)
{
    await RevokeFamilyAsync(connection, transaction, current.FamilyId, ct);
    await transaction.CommitAsync(ct);
    return null;
}

var nextToken = tokenService.GenerateRefreshToken();
var nextHash = tokenService.HashRefreshToken(nextToken);

// Eski kaydı iptal et ve yeni family üyesini aynı transaction içinde ekle.
await RotateAsync(connection, transaction, current, nextHash, ct);
await transaction.CommitAsync(ct);

Gerçek uygulamada kullanıcı aktifliği, expiry, token version, iki faktör doğrulama durumu, issuer/audience ve session kaydı da doğrulanır.

Refresh token rotation nedir?

Rotation, her başarılı yenilemede yeni refresh token üretip kullanılan tokenı geçersiz kılmaktır. Eski ve yeni kayıt aynı FamilyId ile bağlanır. Böylece eski token tekrar sunulduğunda bunun normal bir yenileme değil replay olabileceği anlaşılır.

Rotation işlemi atomik değilse iki paralel istek iki geçerli yeni token üretebilir. Transaction, benzersiz hash ve kaydın güncelleme kilidi bu yarış durumunu önler.

Reuse detection ve token ailesi

Eski refresh tokenın ikinci kez kullanılması “hangi taraf saldırgan?” sorusunu kesin cevaplamaz. Meşru istemci ve tokenı ele geçiren kişi aynı eski değeri sunabilir. Güvenli tepki, aktif token ailesini iptal etmek ve kullanıcıdan yeniden kimlik doğrulaması istemektir.

Kayıtta en az şu alanlar kullanışlıdır:

Alan Amaç
TokenHash Açık tokenı veritabanında tutmamak
SessionId Tek cihaz/oturum iptali
FamilyId Rotation zincirini topluca iptal etmek
ReplacedByTokenHash Eski-yeni ilişkisinin denetimi
ExpiresAt Mutlak sona erme
RevokedAt Kullanıldı veya manuel iptal edildi bilgisi
TokenVersion Rol/parola değişiminde eski oturumları geçersiz kılmak

Refresh token nerede saklanır?

Tarayıcı tabanlı uygulamada XSS ile okunabilen localStorage içine uzun ömürlü token koymak riski büyütür. Güvenli web uygulamalarında tokenların güvenilen backend tarafında tutulduğu BFF/cookie yaklaşımı değerlendirilebilir. Cookie kullanılacaksa HttpOnly, Secure, uygun SameSite, dar Path ve CSRF koruması birlikte tasarlanmalıdır.

Mobil/desktop istemcide işletim sisteminin güvenli credential deposu tercih edilir. Log, exception, analytics payload, URL query string veya ekran görüntüsüne token yazılmaz.

Logout ve revocation

Logout yalnız istemcide token silmek değildir. Sunucu ilgili session veya refresh tokenı iptal etmelidir. Parola değişimi, hesap kapatma, iki faktör değişimi veya kritik güvenlik olayı tüm sessionları ya da ilgili token familylerini iptal edebilir.

Access token stateless ise logout sonrası kısa bir süre geçerli kalabilir. Bu risk kısa expiry, token version/session doğrulaması veya gerekli sistemlerde deny-list ile yönetilir.

Süre nasıl belirlenir?

Evrensel “access token 15 dakika, refresh token 30 gün” kuralı yoktur. Süre; veri hassasiyeti, cihaz türü, tekrar giriş maliyeti, saldırı modeli ve session iptal kapasitesine göre belirlenir. “Beni hatırla” seçeneği daha uzun süre veriyorsa bunu ayrı politika olarak kaydet; sonsuz refresh token üretme.

Hata sözleşmesi

Durum Beklenen davranış
Token boş veya hash kaydı yok 401; ayrıntılı iç bilgi sızdırma
Token süresi dolmuş Aileyi gerektiği kadar iptal et, 401
İptal edilmiş token tekrar kullanıldı Aileyi iptal et, kritik güvenlik olayı yaz, 401
Kullanıcı pasif / token version eski Oturumu iptal et, 401
Geçerli rotation Yeni access ve refresh token dön
Yetki var fakat kaynak izni yok 403; refresh ile karıştırma

Doğrulama senaryoları

  • Aynı refresh token art arda iki kez kullanıldığında ikinci istek reddedilir.
  • Paralel iki yenilemeden yalnız biri başarılı olur.
  • Eski token tekrar kullanıldığında yeni family üyesi de iptal edilir.
  • Parola veya token version değişiminden sonra eski session yenilenemez.
  • Pasif kullanıcı refresh token ile access token alamaz.
  • Veritabanı ve uygulama loglarında açık refresh token bulunmaz.
  • Logout sonrası aynı token yenilenemez.

İlgili rehberler

Kaynaklar

Paylaş:

Bu yazı hakkında sorunuz mu var? İletişime geçin.

İletişime Geç

İlgili yazılar

.NET, API, veritabanı ve kullanıcı arayüzü bileşenlerinden oluşan yazılım mimarisi
.NET, Backend ve API Mimarisi 22.04.2026

ASP.NET Core Web API İçin Üretim Klasörleme Standardı

ASP.NET Core Web API projelerinde katman, bağımlılık yönü, yapılandırma, test ve dağıtım klasörlerini üretime uygun biçimde düzenleyen ayrıntılı rehber.

22 Nis 2026
.NET, API, veritabanı ve kullanıcı arayüzü bileşenlerinden oluşan yazılım mimarisi
.NET, Backend ve API Mimarisi 26.04.2026

Controller İçine SQL Yazmadan Dapper Mimarisi

Dapper sorgularını controller katmanından çıkarıp bağlantı, transaction, parametreleme ve hata yönetimini test edilebilir bir veri erişim katmanında toplama rehberi.

26 Nis 2026
.NET, API, veritabanı ve kullanıcı arayüzü bileşenlerinden oluşan yazılım mimarisi
.NET, Backend ve API Mimarisi 03.04.2026

Repository ve Unit of Work Ne Zaman Kullanılmalı?

Repository ve Unit of Work kalıplarının faydalı olduğu durumları, Dapper ve EF Core üzerindeki gereksiz soyutlamaları ve transaction sınırlarını karşılaştıran karar rehberi.

03 Nis 2026
Ayrılmış kiracılar, roller, ödeme akışı, lisans ve denetim kayıtlarıyla SaaS platformu
SaaS, E-Ticaret ve Ürün Geliştirme 29.07.2026

SaaS Tenant ve Rol Mimarisi

Çok kiracılı SaaS uygulamalarında tenant çözümleme, veri izolasyonu, rol/izin, cache, arka plan işi ve denetim kaydı sınırlarını güvenli tasarlama rehberi.

29 Tem 2026
Sunucu, DNS, TLS, yedekleme ve dağıtım katmanlarından oluşan barındırma altyapısı
DevOps, Sunucu, Bulut ve Dağıtım 14.05.2026

ASP.NET Core Plesk ve IIS Yayını: A'dan Z'ye

ASP.NET Core uygulamasını Windows Plesk ve IIS üzerinde Hosting Bundle, application pool, publish çıktısı, web.config, izinler ve loglarla yayımlama rehberi.

14 May 2026
Sunucu, DNS, TLS, yedekleme ve dağıtım katmanlarından oluşan barındırma altyapısı
DevOps, Sunucu, Bulut ve Dağıtım 08.04.2026

Plesk ve IIS ASP.NET Core Hataları: 500.30, 403 ve CSS Sorunları

Plesk/IIS üzerinde ASP.NET Core 500.30 başlangıç hatası, 403 statik sunum, kayıp CSS, yanlış document root, WebDAV ve API PUT/DELETE sorunlarını teşhis rehberi.

08 Nis 2026