Merhaba Sevgili Okurlar,
Bu yazımızda JWT ile authentication’dan bahsedeceğiz. JWT Authentication token tabanlı stateless bir authentication yöntemidir. Stateless olduğu için ölçeklenebilir sistemlerde genellikle tercih edilir. İlk olarak Identiy.API’mizde JWT ve Refresh Token üretip yazımızın ikinci kısmında da JWT’i validate eden bir API olan Product.API’den bahsedeceğiz.
JWT basit mantıkla bir key ile imzalanıp
sistemde dolaşır ve karşı taraf imzayı doğrulayabildiğinde sisteme giriş
yetkisi alır. Eğer alamazsa API’ler taraından 401 Not Authorized cevabını alması
gerekir.
JWT, "Json Web Tokens" anlamına gelir. Header, payload ve verify signature olmak üzere üç kısımdan oluşur. Bu linkten bir JWT’nin yapısını inceleyebilirsiniz. JWT authentication akışını aşağıdaki görselde özetleyebiliriz.
İyi bir JWT Authentication akışında hem JWT hem de Refresh Token olmalıdır. Refresh token’in expire süresi, JWT expire süresine göre uzun olmalıdır. Örneğin Refresh Token süresi 1 gün olurken JWT süresi 10dk olabilir. JWT expire olduğunda refresh token ile Identity API’ye gidilip yeni JWT alınmalıdır. Eğer Refresh token’de expire olursa kullanıcı login sayfasına yönlendirilip yeni JWT ve Refresh token alınmalıdır. Token’lerin süresi uygulamaya uygulamanın amacına göre değişebilir.
İlk olarak GenerateToken (/token) metodumuzu inceleyelim. Bu metod’da JWT ve Refresh Token’larımızı üretiyoruz. Kullanıcı token üretmek için kullanıcı adı ve şifresini gönderiyor eğer sistemde böyle bir kullanıcı yoksa token üretilmiyor. Ayrıca kullanıcı token’i revoke olmuş ise yine token üretilmiyor.
Benim yazdığım örnek kodda her kullanıcıya DB’de tek bir satır ataması yapmak istediğim için generate token metoduna birkaç defa gelen kullanıcılar için eğer geçerli token’i varsa yenisini üretmek yerine geçerli token’ini dönüyorum. Bu senaryoyu kendi ihtiyacınıza göre değiştirebilirsiniz.
Kullanıcının JWT’yi kendi client’inda tutmayıp sürekli API’ye istek yapmaması içinde JWT’yi null bırakıyorum. Böylece kullanıcıyı token aldıktan sonra diğer istekleri için JWT’yi kendi client’inda store etmeye zorluyorum.
JWT Claim list’de bazı özel alanlar var sub role ya da jti gibi bu alanları kullanarak JWT’nizde bilgi taşıyabilirsiniz.
Şimdi ise RefreshToken(/refresh) metoduna yakından bakalım:
Bu metod JWT’si expire olmuş isteklere yeni JWT üretir eğer refresh token da expire olmuş ise yeni refresh token’da döner. Refresh token henüz expire olmamış sadece JWT expire olmuş ise sadece JWT’yi yeniler. RefreshToken metodu sadece Refresh token paremetresi alır. Eğer sistemde bu refresh token var ise yukarıda bahsettiğim işlemleri gerçekleştir. Değilse sistemde refresh token tanımlı değil uyarısını verir.
Eğer uygulamanızda
refresh token expire olduğunda login sayfasına yönlenir gibi bir senaryo varsa
bu metod’da refresh tokeni expire olmuş ise yenilemenize gerek yoktur. Token
metoduna yönlendirip yeni JWT ve Refresh Token ürettirebilirsiniz. Eğer
sisteminiz login sayfasına uygulama yaşam dönüsü boyunca bir kez gitsin
diyorsanız bu yöntemi de tercih edebilirsiniz.
Revoke Token(/revoke) metoduna bakacak olursak JWT ve RefreshToken’i
expire ederek kullanıcının sisteme giriş yapmasını engeller. Fakat JWT sign
edilirken expire süresi belirlendiği için JWT expire süresi boyunca sisteme
giriş yapabilir ne zamanki refresh token ile yeni JWT almaya geldiğinde sistem
kullanıcıya izin vermeyecektir.
JWT Token’in expire süresince bile sisteme sign olmasını istemiyorsanız Validate metoduna bir logic yazabilirsiniz fakat bu logic DB’ye gidip JWT revoke edildi mi gibi bir kontrol olacağında ölçeklenebilir sistemlerde verimli olmayacaktır.
Identity API’nin swagger görünümü aşağıdaki gibidir.
API bu istek sonucunda aşağıda Program.cs ‘de yer
alan metod ile bu JWT’yi validate edip ya başarılı cevap dönecektir ya da
validate edemez ise 401 UnAuthorized cevabı verecektir. Product API token’ı
sign edebilmesi için Identity API ile aynı Valid Audience ve Valid Issuer değerlerine
sahip olmalıdır.
Görüldüğü gibi OnTokenValidated ya da OnAuthenticationFailed metodlarına istediğiniz custom logic’i de kodlayabilirsiniz.
Product API’nin swagger görünümü aşağıdaki gibidir.
Okuduğunuz için teşekkürler, Bu blog yazısı ile ilgili örnek projeyi GitHub hesabımda bulabilirsiniz.
Sağlıkla kalın.
Hiç yorum yok:
Yorum Gönder