2012-12-19 21 views
7

Chciałbym utworzyć backend uwierzytelniania, który pozwala użytkownikom log_in tylko za pomocą ich e-mail (bez nazwy użytkownika, bez hasła).Backend niestandardowego uwierzytelniania. Django

Oto, co próbowałem.

backends.py:

from django.conf import settings 
from django.contrib.auth.models import User 

class EmailAuthBackend(object):  
    def authenticate(self, username=None, password=None): 
     try: 
      user = User.objects.get(email=username) 
      if user: 
       return user 
     except User.DoesNotExist: 
      return None 

settings.py:

AUTHENTICATION_BACKENDS = (
     'path_to.backends.EmailAuthBackend', 
     'django.contrib.auth.backends.ModelBackend', 
    ) 

HTML:

<form method="post" action="{% url myproject.views.test %}"> 
    {% csrf_token %} 

     <input type="text" name="email" value=""/> 

    <button type="submit">Valider</button> 

    </form> 

Wygląd:

def test(request): 
    email = '' 
    if 'email' in request.POST: 
     email = request.POST.get('email') 
     if not User.objects.filter(email=email): 
      User.objects.create(email=email) 
     user = authenticate(username=email) 
     if user is not None: 
      if user.is_active: 
       auth_login(request, user) 
    return HttpResponseRedirect(reverse('home')) 

To nie działa, użytkownik nie jest uwierzytelniony. A ja też mam ten błąd, gdy idę do/admin:

AttributeError at /admin/logout/ 
    'EmailAuthBackend' object has no attribute 'get_user' 

Odpowiedz

11

Dla każdej niestandardowej backend w Django, trzeba określić funkcję get_user. Zobacz the documentation. Realizacja get_user może po prostu użyć istniejącej tabeli użytkownika, jak jesteś:

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

Powodem jest to konieczne jest w sytuacji, gdy trzeba by sprowadzić Użytkownika za pośrednictwem klucza podstawowego z innego źródła.

+0

DZIĘKUJEMY. Akceptuję odpowiedź jak najszybciej. – Marcolac

2

Chociaż przyjęta odpowiedź jest poprawna, podam przykład innego sposobu rozwiązania problemu przez dziedziczenie ModelBackend.

from django.contrib.auth.backends import ModelBackend 

class EmailAuthBackend(ModelBackend): 
    def authenticate(self, username=None, password=None, **kwargs): 
     try: 
      user = User.objects.get(email=username) 
      if user.check_password(password): 
       return user 
     except ObjectDoesNotExist: 
      # Run the default password hasher once to reduce the timing 
      # difference between an existing and a non-existing user (#20760). 
      User().set_password(password) 

Polecenie get_user jest już zaimplementowane przez ModelBackend, a wraz z nim uzyskasz odpowiednie uprawnienia.

Powiązane problemy