• Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim
KodEdu
  • Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim

JWT (JSON Web Tokens) Nedir? Ne işe yarar?

  • Posted by Kodedu
  • Categories Genel
  • Date 9 Mart 2017

JWT (JSON Web Tokens), IETF kuruluşu tarafından tasarlanan standart bir token biçimidir (Bkz. RFC 7519). Haberleşen iki veya daha fazla sistem (Web, Mobile, IOT, Cloud vb.) arasında kullanıcı doğrulama, kullanıcı tanıma, veri bütünlüğünü ve bilgi güvenliğini koruma gibi noktalarda kullanılmaktadır.

JWT’nin avantajları

  • JSON kullanması

  • URL üzerinde taşınabilmesi

  • Web çerezleri kullanma zorunluluğu olmaması

  • CSRF ataklarına karşı daha kapalı olması

  • Hızlı doğrulama yapılabilmesi

  • Kolay ölçeklenebilir olması

  • Web uygulamaları açısından HTTP session gerekmemesi, stateless kullanıma uygun olması

  • Veri bütünlüğünü sağlaması

JWT’nin yapısı

JWT, Base64 biçiminde kodlanmış 3 ayrı JSON parçasından oluşmaktadır. Parçalar nokta (.) sembolüyle ayrılmakta ve bir bütün olarak JWT’yi temsil etmektedir.

JOSE Header

JWT başlık bilgisi JSON biçiminde yazılmakta ve standart bazı alanları bulunmaktadır. Aşağıda genel bir örneğini görmektesiniz.

JOSE HEADER örneği
{
    "alg": "HS256", (1)
    "typ": "JWT" (2)
}
1 Veri bütünlüğünü korumak için kullanılacak cryptotic algoritmayı belirtir.
2 Bir JWT nesnesi olduğunu belirtir

JOSE başlığı token içine eklenirken Base64 biçiminde kodlanır. Örneğin yukarıdaki JSON başlığın Base64 karşılığı ewogICJhbGciOiAiSFMyNTYiLAogICJ0eXAiOiAiSldUIgp9 dir. JWT’nin URL dostu oluşu Base64 gösterimini kullanmasından kaynaklanmaktadır.

JWT Payload

Bir JWT token, bir token üretici ve tüketicisi arasında eşsiz olmalıdır. Bu eşsizliği payload diğer adıyla claim bilgileri tanımlar. Payload içinde kullanıcıya ait kimlik, zaman aşımı ve kullanıcı yetkileri gibi alanlar yer alabilir.

JWT Payload örneği
{
    "userId": "3344552266",
    "expire": 1486220816,
    "roles": ["admin", "user"]
}

Örneğin yukarıdaki JWT payload içindeki userId alanı eşsiz kullanıcı kodunu, expire token zaman aşımı anını, roles ise kullanıcı yetkilerini temsil etmektedir. Bir token içinde expire alanı olması zorunlu değil, yine roles alanı olması da zorunlu değil fakat eşsizlik ve aidiyeti temsil etmek için userId gibi bir alan olması gerekiyor.

Payload içine ne koyulacağı tamamen geliştiricisine bağlı fakat RFC 7519 birtakım isteğe bağlı alan adını standartlaştırmıştır. İsterseniz bu standart isimlendirmeleri kullanabilirsiniz (Bkz. rfc7519#page-9).

Payload JWT token içine eklenirken aynı JOSE başlığında olduğu gibi Base64 biçiminde kodlanır. Yukarıdaki başlığın Base64 karşılığı ewogICJ1c2VySWQiOiAiMzM0NDU1MjI2NiIsCiAgImV4cGlyZSI6IDE0ODYyMjA4MTYsCiAgInJvbGVzIjogWyJhZG1pbiIsICJ1c2VyIl0KfQ== dir.

JWT Signature (JWT İmzası)

3 parçadan oluşan JWT’nin son parçası JWT imzasıdır. İmza kısmı token üreticisi ve tüketicisi arasındaki veri bütünlüğünü garanti etmektedir. İmza oluşturulurken JOSE başlığında tanımlı algoritma kullanılmaktadır.

JWT imzası, JWT başlığı ve JWT payload birleştirilerek aşağıda sıralı adımlarla oluşturulmaktadır.

Base64 kodlaması için temsili doBASE64, HS256 imzalama için temsili doHMACSHA256 fonksiyonu kullanılacaktır.

PART1= doBASE64(HEADER)

PART2= doBASE64(PAYLOAD)

PART1_PART2= PART1 + "." + PART2

SECRET_KEY= "Merhaba KodEdu"

PART3= doBASE64(doHMACSHA256(PART1_PART2, SECRET_KEY))

JWT_TOKEN= PART1_PART2 + "." + PART3

Gizli anahtar (Secret Key) HS256 algoritması için kullanılmaktadır. doHMACSHA256 fonksiyonu, imzalanacak veriyi (PART1_PART2) tanımladığınız anahtarla imzalayarak imza kısmını oluşturur. Veri bütünlüğünün bozulup bozulmadığı ise yine bu fonksiyon ve gizli anahtar ile sorgulanır.

Yukarıdaki işlemler sonucunda JWT token çıktımız aşağıdaki gibi olacaktır.

ewogICJhbGciOiAiSFMyNTYiLAogICJ0eXAiOiAiSldUIgp9.ewogICJ1c2VySWQiOiAiMzM0NDU1MjI2NiIsCiAgImV4cGlyZSI6IDE0ODYyMjA4MTYsCiAgInJvbGVzIjogWyJhZG1pbiIsICJ1c2VyIl0KfQ==.K0VLcjhVQWZMem0yMnF1L280QktFRUZNZ3VHTVNQLzNrVFlMSmMzNjQ5QT0=

Üretilen JWT bilgisini https://jwt.io/ adresinden test edebilirsiniz.

JWT’nin doğrulanması

JWT doğrulamak için, doğrulanacak JWT token nokta (.) ayraçlarından 3 parçaya bölünerek PART1, PART2 ve PART3 olarak ayıklanır. Ardından PART1, PART 2 ve sadece bizim bildiğimiz SECRET_KEY ile yukarıdaki adımlarla JWT imzası hesaplanır. Hesaplanan JWT imzası ile ayıklanan PART3 aynı ise JWT token doğrulanmış olur. Aynı değilse token geçersiz demektir.

JWT’nin uygulanışı

JWT standardını uygulayan birçok açık kaynak kütüphane bulunmakla birlikte, bu yazıda sizlerle JWT için yukarıda bahsedilen adımları uygulayan bir örneği paylaşmak istiyorum.

SHA-256 üretme adımı
public String doHMACSHA256(String part1AndPart2, String secretKey){
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(new SecretKeySpec(secretKey.getBytes(), "HmacSHA256"));

    byte[] hashBytes = mac.doFinal(part1AndPart2.getBytes());
    String hash = doBASE64(hashBytes);
    return hash;
}
Base64 üretme adımı
public String doBASE64(byte[] bytes) {
    Base64.Encoder encoder = Base64.getEncoder();
    String base64 = encoder.encodeToString(bytes);
    return base64;
}

public String doBASE64(String input) {
    byte[] bytes = input.getBytes(Charset.forName("UTF-8"));
    String base64 = doBASE64(bytes);
    return base64;
}
JWT üretme adımı
public String generateJWT(){

    String HEADER = String.join("\n", Files.readAllLines(Paths.get("./header.json")));
    String PAYLOAD = String.join("\n", Files.readAllLines(Paths.get("./payload.json")));

    String PART1 = doBASE64(HEADER);
    String PART2 = doBASE64(PAYLOAD);

    String PART1_PART2 = PART1 + "." + PART2;

    String PART3 = doBASE64(doHMACSHA256(PART1_PART2, SECRET_KEY));

    String JWT_TOKEN = PART1_PART2 + "." + PART3;

    return JWT_TOKEN;
}
JWT doğrulama adımı
public boolean validateJWT(String jwt) {

    String[] parts = jwt.split("\\.");
    String PART1 = parts[0];
    String PART2 = parts[1];
    String PART3 = parts[2];

    String PART1_PART2 = PART1 + "." + PART2;

    String jwtSignature = doBASE64(doHMACSHA256(PART1_PART2, SECRET_KEY));

    return jwtSignature.equals(PART3);

}
Çalıştırma adımı
String JWT_TOKEN = generateJWT();

boolean isValid = validateJWT(JWT_TOKEN);

System.out.println("Is valid ? " + isValid);

Uygulama kodlarına https://github.com/rahmanusta/JwtDemo adresinden erişebilirsiniz.

Faydalı olması dileğiyle.

  • Share:
author avatar
Kodedu

Previous post

Letsencrypt ile websitenizi ücretsiz SSL'e geçirin
9 Mart 2017

Next post

Spring Cloud Netflix'e Giriş
24 Nisan 2017

You may also like

api-logo
Swagger Nedir? Neden kullanılır?
10 Ekim, 2018
spring-cli-logo
Spring CLI ile Spring Boot Projeleri Hazırlamak
21 Ağustos, 2017
eureka_architecture
Spring Cloud Netflix ve Eureka Service Discovery
3 Temmuz, 2017

    4 Comments

  1. Tuğba
    11 Mart 2019
    Cevapla

    Merhaba, yazınız için teşekkür ederim. JWT’nin Türkçe olarak anlaşılması için çok güzel bir kaynak.
    JWT Payload örneği kısmında, user’ın başka bilgilerini de kullanmaya çalıştığımda hata aldım. Bu bilgilerden hangileri kullanılabilir ? userMail bunun için kullanılabilir mi ?
    Teşekkürler.
    İyi Çalışmalar.

    • Rahman Usta
      29 Mart 2019
      Cevapla

      Merhaba, kullanmadınızda bir sakınca bulunmuyor. Paylaşılan kodu modifiye ederek deneyebilirsiniz.

  2. Furkan
    3 Mayıs 2021
    Cevapla

    Selamlar, JWT hakkında temel bilgilere bu makale sayesinde ulastım. Tesekkürler Rahman.

Leave A Reply Cevabı iptal et

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta listesine kayıt olun!






Gözde yazılar

Netmera ile Röportaj
18Haz2012
Spring CLI ile Spring Boot Projeleri Hazırlamak
21Ağu2017
Performans, Yük ve Stres Testleri
26Ağu2012
CDI – @Produces, @New ve @PostConstruct Notasyonları
22Tem2013

Son Yazılar

  • Java’da Record’lar 27 Ocak 2020
  • Swagger Nedir? Neden kullanılır? 10 Ekim 2018
  • Spring CLI ile Spring Boot Projeleri Hazırlamak 21 Ağustos 2017
  • Spring Cloud Netflix ve Eureka Service Discovery 3 Temmuz 2017
  • Online React.js Eğitimi ardından (15-25 Mayıs 2017) 31 Mayıs 2017

Son Yorumlar

  • Coupling ve Cohesion Kavramları Nedir? için Hilal
  • Naïve Bayes Sınıflandırma Algoritması için Rahman Usta
  • Naïve Bayes Sınıflandırma Algoritması için Mete
  • YAML Nedir? Neden YAML Kullanmalıyız? için kara
  • JWT (JSON Web Tokens) Nedir? Ne işe yarar? için Furkan

Get Java Software

Arşivler

Bizi takip edin

React.js Eğitimi Başlıyor
11-22 Eylül, 2017
Eğitmen
Rahman Usta
İletişim

merhaba@kodedu.com

  • Hakkında
  • Gizlilik Politikası
  • İletişim
  • Referanslar
Kodedu Bilişim Danışmanlık
Cemil Meriç mah. Çelebi sok.
No:16/3 Ümraniye/İSTANBUL
Tel: 0850 885 38 65
Alemdağ V.D.: 8960484815

KODEDU © Tüm hakları saklıdır.