Flask ve JWT ile Authentication İşlemleri

Selamlar bu yazıda Flask ve JWT ile Authentication İşlemleri hakkında bazı bilgiler vereceğim. Bir önceki yazı Caddy Server ve PHP hakkındaydı. Yazıyı yazarken virtualenv kullanacağım. Eğer yok ise onu kurmakla başlayabilirsiniz.

Flask ve JWT ile Authentication İşlemleri

Flask ve JWT ile Authentication İşlemleri

Bu yazıda virtualenv kurulumunu göstereceğim. Virtualenv ile Flask, JWT gibi modülleri geliştirici ortamımıza indireceğiz. Basit olarak bir decorator yazıp her defasında token var mı yok mu kontrolü yapmaktan kurtulacağız. Ayrıca JWT resmi sitesinden ortaya çıkan token geçerli mi değil mi kontrolü yapacağız. Son olarak da bu yazının sonunda, anlatılan bilgilerin aktarıldığı Github repositorysini bulacağız.

Nerede Kullandım?

Bu yazıyı yazmadan önce JWT bir ihtiyaç oldu. Aslında JWT olmadan da giderilebilecek bir ihtiyaç fakat güvenlik gibi nedenlerden ötürü hard data saklamaktan kaçınıyoruz. Vue ya da envai çeşit SPA Framework ile kullanıcıların giriş yapıp data insert edeceği sistemler inşaa edebiliriz. Bunun gibi bir sistemi ben de deniyordum. İyi de session işi nasıl hallolacak konusunda bir hayli takıldım. Araştırınca JWT üzerine gidildiğini gördüm. Bir diğeri de Okta bu arada.

Virtualenv İle Geliştirme Ortamımızı Hazırlayalım

Henüz bilinmiyorsa söyleyeyim, virtualenv dediğimiz şey izole şekilde Python geliştirme ortamı oluşturan bir tool. Her proje kendi ekstra modüllerine sahip olur. Bu modüller sadece o proje kapsamında kullanılır. Yani bu sistemi bir yere taşıdığınızda tekrar tekrar o modülleri sisteme kurmanız gerekmez zaten bunları freeze edersiniz. Eğer yok ise önce virtualenv kuralım:

Ardından geliştirme ortamımızı ayarlayalım. Ben şu anda ~/Projects/py klasörü altında bulunuyorum. Şu komutları girelim:

Eğer işlem başarılıysa konsol ekranı şöyle görüntülenecek:

Şu anda bize lazım olan şey Flask ve PyJWT modüllerinin kurulumu. Konsolu kapatmadan şu komutları girelim:

Bu komutlarla JWT ve Flask kurulumunu gerçekleştirdik. Hemen bir adet main.py dosyasını bu dizine açalım. Eğer VSCode gibi editörler kullanıyorsanız entegre terminalde virtualenv ile çalışabilirsiniz. Basit bir Flask yapısı şöyle olsun:

Kısacası şöyle bir istekte bulunmuşuz gibi olacak: http://127.0.0.1:2121/api/v1/user/2 Ancak bu istekte bir SPA tarafında session problemi yaşamamız olası. Şimdi kullanıcı girişi ve kullanıcı kaydı için iki adet route oluşturacağız. Senaryo şu, kayıtlı kullanıcı id’si verilen bir başka kullanıcıyı görebilir. Bunun için de JWT tarafında valide edilmiş bir anahtara ihtiyacımız var. Önce rotalarımızı yazalım. Senaryoya göre kullanıcı kayıt olacak giriş yapacak. Bizim için kayıttan ziyade giriş önemli.

Şimdi login işleminde eğer veri tabanında yaptığımız sorgunun sonucu doğru dönüyorsa hash oluşturalım. Bu hash değerinde normalde parola vs. saklamayın ama ben örnek data olarak bunları döndüreceğim. Bu hash için flask özelinde bir secret key belirtelim ve ayrıca datetime modülünü içeriye aktaralım. Dosyanın en üstüne

ekleyelim ve ardından app değişkeninin hemen altına secret key tanımlayalım. Kısacası üst kısım şöyle olacak:

Son haliyle bu işlemlerden sonra login işlemini yaptırdığımız metodumuz şeklini aldı:

user ve password değerleri bizim özelimizde bir değer iken, exp değeri “expiration time” yani tokenin sona eriş tarihini veriyor.  JWT ile bazı claimler kullanabilirsiniz. (Buradan bakınız). Bu tarih nereden geliyor? Şu anki zamanımızı alıyor ve bu zamanın üzerine 30 dakika ekliyor. Bu kodu şöyle de yapabilirdik:

Yukarıdaki kod token 24 saat geçerli olacaksa kullanılabilir. Ancak şu an örneğimiz 30 dakika üzerinden ilerliyor. Burada jwt’ye ait encode metodu, ilk parametreyi obje türünden bir payload şeklinde alırken, ikinci parametresi secret key yani çok gizli anahtarımız oluyor. Bu anahtarı zaten ön yüzde saklamak pek mantıklı değil de oldu da backend projenizi git gibi public bir ortama attınız işte o zaman sorun oluyor. O yüzden .env gibi çözümler ideal oluyor.

Ardından basit bir login isteğinde bulunalım:

Flask ve JWT ile Authentication İşlemleri

Çıkan Token İçin Doğrulama İşlemi

Çıkan token tarafında doğrulama işlemini jwt.io üzerinden gerçekleştireceğiz.

Flask ve JWT ile Authentication İşlemleri

Çıkan token üç parçalı base64 değerden oluşuyor. Algoritmayı, payloadı ve secret key’in şifrelenmiş halini içermekte. Özellikle bize ait password ve username değeri burada ortadaki şifreli değerde saklı. Bunu herhangi bir base64 decode sitesinde hemen çözersiniz. Eğer bu expiration time değeri 30 saniye olsaydı bu imza kullanılamayacaktı.

Şimdi az önceki user id endpointine geri dönelim. Metodumuzu şöyle değiştirelim:

Postman ile isteğimizi şöyle gerçekleştirelim:

Alınan Token Değerinin Decode Edilmesi

Bu değerin geçerli bir değer olup olmadığını decode ederek görelim. Yine bu istekte bulunduğumuz metod içinde bazı değişiklikler gerçekleştireceğiz:

Şu anda decode işlemini gerçekleştirdik. Bu istekte yolladığım token 5 saniyelik bir token değerine sahipti. Bu yüzden bir hata aldım. O hata şuna benziyor:

Buradan da anlayacağımız üzere token geçerliliğini kaybetmiş durumda. Gidip 30 dakikalık bir tane alayım hemen 🙂 Yeni çıkan 30 dakikalık token ile birlikte istek yolladığımızda çıkan dönen json değer bir hayli mutlu etti beni:

Şu anda başarılı bir şekilde token tabanlı doğrulamayı yaptık diyelim. Örneğin angular projesinde ya da vue projesinde bu token’i localStorage gibi bir ortamda saklarsınız. Oradan alır ve endpointe bu tokeni basarsınız. Sistem doğru çalışıyor tamam da her yazdığımız route için if token ise falan kontrolünü yapmayalım bi zahmet. Gidip bunun için bi decorator yazalım işimizi de kolaylaştırmış olur. Ben şöyle bir decorator yazdım.

Yetkilendirme İçin Wrapper Yazalım

Kullanıcı ile etkileşime geçen her route mutlaka token değerine sahip olmalı. Eğer token zorunlu değilse belirtmezsiniz. Yazdığımız decorator ve route metodunda kullanımı şöyle olacak:

Yukarıdaki auth decoratorunde token route decoratörüne geçirilmiş olabilir ya da query stringden gelmiş olabilir ya da form post edildiği anda gelmiş olabilir. Bu durumları düşünerek böyle bir kontrol sağladık. Siz bunu daha ileri şekilde kullanabilirsiniz. Bunun doğrulamak adına bir adet post değeri içeren method da yazalım:

Evet token doğru olduğu için, bu metod ne istediysek onu döndürdü. Son durumda yazdığımız kodlar şu şekilde:

Nasıl Kullanırım?

Yukarıda başlarda belirttiğim üzere isterseniz bunu SPA Frameworkler ile gerçekleştirdiğiniz uygulamalarda kullanabilirsiniz. Yani localStorage tarafında tutacağınız, expiration time değeri makul olan token her route’a gönderilir. Eğer token invalidate yani geçersiz ise kullanıcının bulunduğu sayfayı login’e yönlendirirsiniz.

Bu payload üzerinde user id, username, name, surname gibi basit değerleri tutmak isteyebilirsiniz. Ancak bir parola tutmak! Asla 🙂 Sonuçta bu token veri tabanı sorgusundan geçtikten sonra üretilip kullanıcıya sunuluyor yani kullanıcı zaten giriş yapmış demektir.

Söz verdiğim gibi uygulamanın Github linki:

https://github.com/aligoren/flask-jwt-app

Yararlı Linkler

Bu kısımda JWT ve Python ile çalışırken işinize yarayacak linkler yer alıyor:

Yazının sonuna geldik arkadaşlar. Yazı biraz uzun oldu. Bunun için öncelikle affınıza sığınıyorum.

admin

Hi. I'm Ali. I'm 23. I graduated Mehmet Akif Ersoy University from CS Related Department. I can code with all programming languages. But today I'm writing .NET and JavaScript.

You may also like...