Misaliperver: JWT İle Auth İşlemleri? (Json Web Token 2. Kısım)



Selamlar,

Nodejs - Express - Jwt diye başlayalım, yazının sonunda küçük bir uygulama yapıp, session'ı sonlandırırız diye düşünüyorum.

Neydi bu JWT diyorsanız yazının ilk bölümüne aşağıdaki linke tıklayarak gidebilirsiniz. 


Sevgili canımcım bana bir Xiomi akıllı bileklik aldı. Gayet güzel, insan kullanmayınca gerek yok diyor kendimden biliyorum, işin ilginci kullanmaya başlayınca küçük küçük özellikleri sizi kendine çekiyor. Spor yaparken harcadığın kaloriyi, müzik dinlerken telefon uzaktaysa müziği aç/kapa falan etkili değil, ama mutlu ediyor. Sanırım hakimiyet dürtüsü insanı bu küçük şeylerden tatminiyet duygusunu besliyor.

Es verdiğim bu küçük demeçten çıkarmanız gereken sonuç şu, jwt şart değil ama kullanmaya başlayınca; biraz şuraya jwt süreyim, azıcık şuraya da ekliyim, şurada olmazsa olmaz...

Buna kapılmamak lazım, şimdiden uyarmış olayım.

NodeJs Kurulumu

Daha önce global olarak eklemediyseniz, hemen terminali açıp bilgisayarınıza express-generator modülünü kuruyorsunuz.

npm install -g express-generator

Bu modül sayesinde nodejs express "hello world uygulaması" 'na daha hızlı start vereceğiz.

Modül yüklendikten sonra terminalden ilgili klasör altındayken ( mkdir hellojwt ) aşağıdaki komudu çalıştırıyoruz.
 
express . --no-view 

Bu komut sayesinde express altyapısı için user ve index router'larından oluşan temel bir express uygulama altyapısı otomatik olarak oluşturuluyor.

 Otomatik oluşturulan yapı Bizim public klasörü ile işimiz yok
 
 

Şimdi eslint kuralım da, uygulamamız şenlensin. Mocha-Chai ile küçük bir unit test ortamı kurarsak tamamdır. Bir başlık altında alabildiğine konuyu aradan çıkarmış oluruz. İlerde bahsedeceğimiz konulara da davetiye çıkarmış oluruz. Müt-hiş-im!

npm install --save-dev eslint mocha chai chai-http

Eslint'i -g olarak yüklemeyelim. Scripts olarak erişip çalıştırabilelim.
Tercihtir;  npx eslint --init  bu işlemi yapmanızı gerektirmez.
Eslintin kurumunda seçenekleri işaretleyeceksiniz. Aşağıda seçtiklerim bu proje özelinde yeterli olacaktır. (Es6 ile yazıp Babel de kurmak zorunda bırakmayacağım sizi :) )
  
 

Neyse package.json'a yazmanıza gerek yok, bir sürü teknoloji var. Grunt var mesela hoştur, iyidir, tasklarınızı sırasıyla çalıştırırsınız. Bundan sonrasında npx ile devam edeceğim kontrollerime..

npx eslint .   yapalım ve kodun tamamında, eslint kurallarımıza uyulmuş mu bir bakalım...


express-generate ile kurduğumuz hazır projede app.js, routes/index.js, routes/user.js 'de oldukça fazla kurallarımıza uyaman satır var. Girip tek tek düzeltebilirsiniz, otomatik çözebileceklerini eslint'in insiyatifine bakabilirsiniz.

  • String ifadeler " çift tırnak olacak.
  • Satırlar ; noktalı virgül ile kapatılacak.
  • camelCase olarak değişkenler ifade edilecek.

Bu kadar kural yeterli detayı sonra.

npm install --save jsonwebtoken

Nodejs için jwt kütüphanemizi hemen dahil edelim. lib diye bir klasör oluşturup, içine auth.js isimli bir dosya ekleyelim.


Fonksiyonumuza küçük kontroller ekledim, siz bu şekilde yapmak zorunda değilsiniz. Bağımlılığımızı ekledim en üstte ( jsonwebtoken ). Ardından simpleDataBase diye bir değişken oluşturup, sanki database isteği atıyormuş gibi yaptım. (Buraya ben dayanamam ilerde mongoDb ekleriz.)
User giriş bilgileri doğruysa üretim, jwt üretilecek.




Bir önceki yazımızda gördüğümüz gibi çok fazla ayrıntıya girmeden, 24 saatlik token'ımızı oluşturduk. Şimdi bunu bir routes'a ekleyelim.
Proje küçük o yüzden direk user.js içerisinde /login action tanımlayıp, içerisinde jwt'mizi üretelim. İstek post olması güvenliği arttıracak bir yöntem ama öğrenme aşamasında olduğumuz için get olarak login işlemi tanımlayalım.


Burada ne yaptık, url'de query string olarak gelen username ve password değerlerini değişkenlere atamaya çalıştık. Eğer değerler gönderilmediyse geriye http header401 olarak ayarlayıp, hatalı istek gövdesini json olarak response ettik.

Eğer değerler varsa, oluşturduğumuz fonksiyona gönderip, sanal database'imizde her şey güzelse geriye token'ımızı header'ı 200 olarak işaretleyip geri döndük.


 Gayet güzel. Sırada kullanması var.

Tarayıcımdan aşağıdaki gibi istek attığımda;

Aldığım cevap;
{"success":true,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1pc2FsaXBlcnZlciIsImlhdCI6MTU5MjA1MTI1NCwiZXhwIjoxNTkyMTM3NjU0fQ._7dw8Omtaww66rkpLyNCedpVjHrzdfLbUEz2hn_rqV4"}



Şimdi RSA 256 ile şifrelemek signature kısmını uzun tuttuğu için ve şifreleme anahtarı uzun olduğunda brutforce yöntemine karşı daha sağlam bir yöntem olduğunu düşünüyorum ve daha çok kullanıyorum. O da zor değil, şifreleme türlerinden ayrıca bahsedeceğimiz günler gelecek.

Şimdi token'larımızı kontrol edecek bir fonksiyon tasarlayalım ve yetkilendirme gereken web api'lerimizden önce middleware olarak fonksiyonumuzu ekleyelim. Aslında burada request'e kullanıcı verilerini de inject edebiliriz. Bu konuyu database ile reel bir bağlantı kuracağımız başka bir blog'a saklayabiliriz.


Burada yeni bir fonksiyon tasarladık kod adı IsAuthenticate. Bu fonksiyon middleware olarak çalışacak. İçerisindeki req, res, next parametreleri, express kütüphanesinden inject edilecek.

jwt.verify ile token'ımızı, sahip olduğumuz secretkey ile kontrol edeceğiz. Uygun değilse geriye, "user have not permission" döneceğiz. Tabiki token'ın expire süresi dolmuş olabilir veya başka bir durum mevzu bahis olmuş olabilir ama kötü niyetli kullanıcılara açık davetiye çıkarmaya gerek yok diye düşünüyorum. 


Burada bizim kullanıcıya geri dönüş yapmadan önce handle edeceğimiz bir fonksiyon var. Geriye "hos geldin cınım" dönecek. bu foksiyondan önce tezgaha IsAuthenticate diye bir fonksiyon ekliyoruz. Bu fonksiyon token kontrolünü yapıyor. token uygun değilse, burada gördüğünüz fonsiyona daha gelmeden geriye token hatası dönüyor.

Tarayıcımdan aşağıdaki gibi istek attığımda;

Aşağıdaki dönüşü alıyorum;
{"success":true,"message":"Hoşgeldin cınım!"}


Bir untitest yazabiliriz değil mi?

routes klasörünün altına test.js dosyası oluşturuyorum. Ve kodlarımızı yazmaya başlayalım. Öncelikle bin/www  js klasörüne gelip, module.exports = server;  kod bloğunu ekleyerek, http server'ın özelliklerine, chai'nin erişebilmesini sağlayalım.

module.exports = server;

routes klasörü altına test.js dosyası yaratıp, test senaryolarımızı yazmaya başlayalım.

Aşağıdaki şekilde routes içerisine test.js adında bir dosya oluşturup, içerisine chai ile test senaryolarımızı yazıyoruz.



Gayet güzel oldu. Tabi burada bir önceki blogta anlatmaya çalıştığımız teoriyi ve algoritmaları nodejs kullannarak etli budaklı gerçekliğe büründürdük. Bunları ezberlemenizi önermiyorum. Bunları alıp kodları yapıştırmanız da hoş olmayacaktır. Araştıracağınız kanallar belli, buralara girip kurcalamak lazım. Kullandığım teknolojilerin bir kısmını da sizlerle paylaşmaya çalıştım.

Hedefim, küçük olarak anlatmaya başladığım teknolojileri de kapsayacak şekilde, küçük seriler halinde videolar ile bu teknolojilere aşinalığı arttırmak için eğlenceli içerikler üreteceğim. Bunu yıllardır küçük küçük yapıyorum ama işi biraz büyütme zamanı geldi sanırım. Ben bildiğim şeyleri, Türkçe olarak anlatmayı seviyorum. Ve Türkiye'de içerik havuzu oluşturulmasında, iş çağına gelmiş birey olarak sorumluluklarımın olduğunu düşünüyorum.

Bizi takip edecek nesillerin daha iyi imkanlarla yola çıkması için bugün vaktimizi ayırıp tecrübelerimizi aktarmamız gerektiğini düşünüyorum. 

--> Buraya bir github linki gelmesi çok muhtemel :)


Yorumlar