django için “gerçek” @login_required dekoratörü
django-developers ve django-users mail listelerini takip ediyorum. Django ile uygulama geliştirmeye meraklı arkadaşlara da tavsiye ederim. geçenlerde gördüğüm şu thread ise dikkat çekici.
django auth bünyesinde ufak bir decorator barındırıyor. view dosyalarınızın başına koyduğunuz @login_required ile o kısma sadece sisteme giriş yapmış kullanıcıların girebilmesini basitçe sağlıyorsunuz. Django’nun auth modülünün tasarımında kullanıcı pasif durumda olsa bile, authenticated (yetkilendirilmiş) sayılıyor. ilgili dekoratörümüz login_required ise gerekli kontrolü yaparken is_authenticated() değerine bakıyor.
sorun şu ki, pasif bir kullanıcı giriş yapmaya çalıştığında hesap bilgilerini doğru girerse is_authenticated() True dönüyor. is_active kolonu False dönse de. bu da görmemelere gereken sayfaları görebiliyor, yapamamaları gereken işlemleri yapabiliyor olmaları demek.
işin kısası, pasif kullanıcılarınız pek de pasif değiller eğer login_required dekoratörüne güvendiyseniz. aşağıda kendi projem için yazmış olduğum decorator var, projeniz içinde herhangi bir yere gömüp view fonksiyonlarınızdan önce @activeMemberOnly şeklinde kullanabilirsiniz.
from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth.decorators import user_passes_test def activeMemberOnly(function=None, redirect_field_name=REDIRECT_FIELD_NAME): actual_decorator = user_passes_test( lambda u: u.is_authenticated() and u.is_active, redirect_field_name=redirect_field_name ) if function: return actual_decorator(function) return actual_decorator
Ellerine sağlık emre güzel yazı. Ben, doğrulama yapmamış ve göremiyeceği sayfalar için @permission_required kullanıyorum. Gerçi login_required ile tam farkını anlayamadım sanırım, sadece login sayfasına döndürmek dışında.
login_required, kullanıcının sadece hesap bilgileriyle doğru bir şekilde giriş yapıp yapmadığını kontrol ediyor. genelde, sadece üyelerin göreblieceği/işlem yapabileceği view’ler için kullanılır.
permission_required, farklı bir kontrol yapıyor. kaç tane model mevcutsa django o kadar otomatik permission oluşturuyor. uygulama_ismi.change_model_ismi, add_model_ismi gibi
asıl sorun şu ki, kullanıcı pasif olduğunda permission’ları da iptal edilmiyor. permission_required() ile de aynı sıkıntı olacaktır diye düşünüyorum, kontrol etmek lazım.
düzenleme: [şimdi baktım, permission_required(), kullanıcının aktif olup olmadığına da bakıyor.]
en temizi aslında, eğer kullanıcı pasifse, giriş kontrolü yapılırken authenticate() fonksiyonundan sonra logout(request, user) ile “anonymous user” statüsüne düşürmek tekrardan. o zaman login_required/permission_required olduğu şekilde kalabilir. ki bu da şimdi aklıma geldi, ek bir decorator’den daha güzel bir çözüm olarak duruyor
@login_required is_active’i kontrol etmiyor olabilir. Ama aktif olmayan kullanıcılar zaten giriş yapamıyor. Bkz: django.contrib.auth.forms.AuthenticationForm.clean()
Her view çağrısı için bu testi uygulamak yerine giriş sırasında bir kere uygulamak daha akılcı gibi.
Atamert, bu yazıyı yazdığım vakitlerde, django-auth ile gelen form’u kullanmıyordum giriş için. kendim handle ediyordum login ve authenticate fonksiyonlarıyla.
en temizi, en güzeli o gibi duruyor