İçeriğe geç

Django ile Kullanıcı Kimlik Doğrulama Yöntemlerini Özelleştirme (Authentication Backends)

Herkese merhabalar. Muhtemelen Django ile bir proje geliştirdiyseniz kullanıcı giriş,çıkış gibi aksiyonlara ihtiyacınız olmuştur. Yerleşik gelen auth uygulaması sayesinde bu işlemler çok kolay bir şekilde gerçekleştirilebiliyor. Eğer yerleşik kullanıcı modelini özelleştirip username field’ını ezmemiş iseniz kullanıcı adı ve parolanız ile sisteme giriş yapabiliyorsunuz.

Fakat bu her zaman yeterli olmayabiliyor.

  •  Mail serverleri, sosyal ağlar (Facebook,Twitter,Google+) gibi Django dışı servisler ile giriş yapmak istersek isteyebiliriz.
  • Kullanıcıların giriş yaparken kullancı adı,mail adresi veya TCKNO kullanabilmelerini isteyebiliriz.

Bu gibi durumlarda yerleşik doğrulama mekanizması(authentication backend) yeterli gelmeyecektir ve özelleştirmemiz gerekecektir.

Authentication Backend nedir?

Django sisteme giriş isteği aldığında gelen bilgiler ile veritabanında kullanıcıyı bulmaya, parolasını doğrulamaya ve eğer sisteme giriş yapabilecek ise hangi izinlere sahip olduğunu belirlemek amacıyla yaptığı işlemler bütünüdür.


2. örneği ele alalım ve şöyle bir senaryo oluşturalım. Kullanıcı sisteme kullancı adı ya da mail adresi kullanması fark etmeksizin giriş yapabilsin.

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import BaseBackend


UserModel = get_user_model()

class EmailAuthBackend(BaseBackend):
    def authenticate(self, request, *args, **kwargs):
        try:
            user = UserModel.objects.get(email=kwargs["username"])
            if user.check_password(kwargs["password"]):
                return user
            return None
        except UserModel.DoesNotExist:
            user = None

    def get_user(self, user_id):
        try:
            return UserModel.objects.get(id=user_id)
        except UserModel.DoesNotExist:
            return None

İlk olarak BaseBackend i miras alıyoruz.

Özelleştirilmiş bir doğrulama mekanizması oluştururken 2 tane gerekli metod bulunmakta. İlk metod authenticate. Görevi view tarafında çağrılırken gönderilen parametreler ile veritabanında kullancıyı aramak sonrasında,parola kontrolü yapmak ve kullancıyı geri dönmek. Kullanıcıyı bulamaz veya bulduğu halde parola doğrulanamamış ise None dönerek isteğin başarısız olduğunu bildirmek.

İkinci metod ise benzersiz bir attribute ile kullanıcıyı veritabanında arar. Genellikle Primary Key kullanılır. Bulunamazsa None dönülür. Eğer bulunur ise kullanıcı dönülür.

Dipnot get_user metodu kullanıcının is_active özelliğinin kontrolü yapılırken, bir diğer metod olan user_can_authenticate metodü ile birlikte  kullanılır.  Bildiğiniz üzere Django is_active=False özelliğine sahip kullanıcıların giriş yapmasına izin vermez. Fakat özelleştirilmiş doğrulama mekanizmalarında bu özellik atlanabilir. Fakat yine de tanımlanılması gereken 2 metoddan biridir. Diğer metodlar için ise (permission kontrolleri vb)  alttaki linke bakılabilir.

https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#writing-an-authentication-backend

Tamam ise yazdığımız bu backend’i sisteme kayıt etmemiz gerekmekte.

settings.py de

AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    "path.to.EmailAuthBackend",
]

Django authenticate isteği aldığında AUTHENTICATION_BACKENDS değişkenine bakar. Ve yukarıdan aşağıya çalıştırır. Herhangi biri başarılı olduğu anda kullanıcı doğrulanmış olur ve sisteme kabul edilir. İlk kayıt edilen default olarak bulunan auth uygulaması tarafından kullanılan doğrulama mekanizmasıdır. Diğeri de bizim email doğrulaması için oluşturduğumuz backendin yolu.

Let’s test!

from django.test import TestCase

class AccountTest(TestCase):
    def setUp(self):
        self.user = get_user_model().objects.create_user(
            username="test", password="super_secret", email="test@gmail.com"
        )

    def test_user_login_with_email(self):

        self.assertTrue(
            self.client.login(username="test@gmail.com", password="super_secret")
        )

    def test_user_login_with_username(self):
        self.assertTrue(self.client.login(username="test", password="super_secret"))
./manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..
----------------------------------------------------------------------
Ran 2 tests in 0.639s

OK
Destroying test database for alias 'default'...

Her şey tamam görünüyor. Görüldüğü üzere Django’yu yapılacak iş doğrultusunda özelleştirmek çok çok kolay.

Başka bir yazıda bu konu ile alakalı olarak, sosyal uygulamaları kullanarak nasıl sisteme giriş yapacağız onlardan da bahsedeceğim. Görüşmek üzere!

 

 

 

 

 

 

Tarih:Blog

İlk Yorumu Siz Yapın

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

Göster
Gizle