2012-12-19 128 views
7

我想创建一个身份验证后端,允许用户只使用他们的电子邮件(无用户名,无密码)登录。自定义身份验证后端。 Django

这是我试过的。

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> 

视图:

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')) 

它不起作用,用户未通过身份验证。当我去到/ admin和我也有这个错误:

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

回答

11

对于Django的每个自定义后端,你需要指定get_user功能。见the documentation。该get_user实现可以简单地使用现有的用户表,像你:

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

这是必需的原因是为了在那里你需要通过从不同的来源它的主键来抓取用户的情况。

+0

谢谢。我尽快接受答案。 – Marcolac

2

虽然接受的答案是正确的,但我只是提供了另一种通过继承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) 

get_user已由ModelBackend实现,您将获得权限方法。

相关问题