2016-05-19 5 views
28

Я хочу, чтобы django аутентифицировал пользователей по электронной почте, а не через usernames. Один из способов может предоставить значение электронной почты как значение имени пользователя, но я этого не хочу. Причина в том, что у меня есть url /profile/<username>/, поэтому у меня не может быть URL-адрес /profile/[email protected]/.Django - Войдите с электронной почтой

Другая причина, заключающаяся в том, что все электронные письма уникальны, но иногда случается, что имя пользователя уже принято. Следовательно, я автоматически создаю имя пользователя как fullName_ID.

Как я могу просто изменить, пусть Django аутентифицируется с помощью электронной почты?

Вот как я создаю пользователя.

username = `abcd28` 
user_email = `[email protected]` 
user = User.objects.create_user(username, user_email, user_pass) 

Вот как я могу войти.

email = request.POST['email'] 
password = request.POST['password'] 
username = User.objects.get(email=email.lower()).username 
user = authenticate(username=username, password=password) 
login(request, user) 

Есть ли какой-либо другой логин помимо получения имени пользователя в первую очередь?

ответ

38

Вы должны написать собственный сервер аутентификации. Что-то, как это будет работать:

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

class EmailBackend(ModelBackend): 
    def authenticate(self, username=None, password=None, **kwargs): 
     UserModel = get_user_model() 
     try: 
      user = UserModel.objects.get(email=username) 
     except UserModel.DoesNotExist: 
      return None 
     else: 
      if user.check_password(password): 
       return user 
     return None 

Затем установите этот бэкенд как ваш Идент бэкэндом в настройках:

AUTHENTICATION_BACKENDS = ['path.to.auth.module.EmailBackend'] 

Обновлено. Наследовать от ModelBackend, поскольку он уже реализует методы, такие как get_user().

+0

Ницца. Thxs. Вопрос также был очень полезен @PythonEnthusiast. – AlessMascherpa

+0

Ошибка в коде: UserMode.DoesNotExist – cyberbudy

+5

Использование django 1.9.8 У меня есть ошибка: у объекта 'EmailBackend' нет атрибута 'get_user'. Решено путем добавления метода get_user в соответствии с этим методом http: // stackoverflow.com/a/13954358/2647009 – baltasvejas

2

У меня было аналогичное требование, когда либо имя пользователя/адрес электронной почты должно работать для поля имени пользователя. В случае, если кто-то ищет способ проверки подлинности для этого, проверьте следующий рабочий код. Вы можете изменить запрос, если хотите только по электронной почте.

from django.contrib.auth import get_user_model # gets the user_model django default or your own custom 
from django.contrib.auth.backends import ModelBackend 
from django.db.models import Q 


# Class to permit the athentication using email or username 
class CustomBackend(ModelBackend): # requires to define two functions authenticate and get_user 

    def authenticate(self, username=None, password=None, **kwargs): 
     UserModel = get_user_model() 

     try: 
      # below line gives query set,you can change the queryset as per your requirement 
      user = UserModel.objects.filter(
       Q(username__iexact=username) | 
       Q(email__iexact=username) 
      ).distinct() 

     except UserModel.DoesNotExist: 
      return None 

     if user.exists(): 
      ''' get the user object from the underlying query set, 
      there will only be one object since username and email 
      should be unique fields in your models.''' 
      user_obj = user.first() 
      if user_obj.check_password(password): 
       return user_obj 
      return None 
     else: 
      return None 

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

добавить Также AUTHENTICATION_BACKENDS = ('path.to.CustomBackend',) в settings.py

+0

Это отлично работает для меня! – Gui

+0

@GuilhermeJunqueira: круто! – anuragb26

2

Вы должны настроить класс ModelBackend. Мой простой код:

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

class YourBackend(ModelBackend): 

    def authenticate(self, username=None, password=None, **kwargs): 
    UserModel = get_user_model() 
    if username is None: 
     username = kwargs.get(UserModel.USERNAME_FIELD) 
    try: 
     if '@' in username: 
      UserModel.USERNAME_FIELD = 'email' 
     else: 
      UserModel.USERNAME_FIELD = 'username' 

     user = UserModel._default_manager.get_by_natural_key(username) 
    except UserModel.DoesNotExist: 
     UserModel().set_password(password) 
    else: 
     if user.check_password(password) and self.user_can_authenticate(user): 
      return user 

И settings.py файл, добавьте:

AUTHENTICATION_BACKENDS = ['path.to.class.YourBackend'] 
7

Если вы начинаете новый проект, Джанго настоятельно рекомендуется создать пользовательский пользовательская модель. (См https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project)

и если вы сделали это, добавьте три строки в модели пользователя:

class MyUser(AbstractUser): 
    USERNAME_FIELD = 'email' 
    email = models.EmailField(_('email address'), unique=True) # changes email to unique and blank to false 
    REQUIRED_FIELDS = [] # removes email from REQUIRED_FIELDS 

Тогда работы, в то время как authenticate(username=username, password=password) перестает работать.

+0

При запуске createuperuser это само выбрасывает ошибку: TypeError: create_superuser() отсутствует 1 обязательный позиционный аргумент: 'username'. Вы должны использовать менеджер пользовательских пользователь: класс 'MyUserManager (BaseUserManager): Защиту create_superuser (самость, адрес электронной почты, пароль, ** kwargs): пользователь = self.model (электронная почта = электронная почта, is_staff = True, is_superuser = True, ** kwargs) user.set_password (password) user.save() return user' –

+2

Полное руководство здесь: https://www.fomfus.com/articles/how-to-use-email-as- имя пользователя-для-Джанго аутентификации удаляющих-на-имя пользователя – user2061057

Смежные вопросы