Регистрация пользователя и аутентификация по адресу электронной почты вместо имени пользователя - PullRequest
1 голос
/ 04 марта 2012

Я не хочу писать пользовательский аутентификационный бэкэнд, и я думаю, что такая общая задача должна быть уже решена каким-либо сторонним приложением.

Я немного погуглил и просмотрел SO, но нашел только https://bitbucket.org/hakanw/django-email-usernames/wiki/Home, что довольно старо (2008). Какие-нибудь другие альтернативы уже доступны?

Ответы [ 3 ]

7 голосов
/ 04 марта 2012

Вы говорите: «Я не хочу писать пользовательский бэкэнд аутентификации», но пользовательский бэкэнд аутентификации - это именно тот способ, которым Django ожидает, что вы решите эту проблему, и, кроме того, это действительно довольно просто - гораздо проще, чем установка стороннего приложения.

Вот простой подход, при котором пользователь имеет один адрес электронной почты, хранящийся в поле email встроенного объекта User.

Сначала подумайте о чувствительности к регистру. Даже если локальная часть адреса электронной почты (часть перед знаком @) может быть чувствительна к регистру (в зависимости от поставщика электронной почты), встроенное приложение Django auth обрабатывает адреса электронной почты как регистр - нечувствителен (например, при принятии решения, каким пользователям отправлять электронные письма в ответ на запрос сброса пароля). Так что, вероятно, вам лучше относиться к ним так же.

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

ALTER TABLE auth_user ADD UNIQUE INDEX (email);

или, если вы используете Юг , выполните миграцию схемы для приложения auth, в которое вы звоните db.create_unique('auth_user', 'email').

Чтобы обеспечить уникальность без учета регистра, вы должны убедиться, что сопоставление в поле email не учитывает регистр. Я обнаружил, что это уже было, но вы можете сделать что-то вроде:

ALTER TABLE auth_user MODIFY email VARCHAR(75) COLLATE utf8_general_ci;

(или ascii_general_ci, если вы не поддерживаете международные адреса электронной почты .)

В-третьих, определите ваш бэкэнд аутентификации , возможно, в mysite/backends.py:

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User

class EmailAuthenticationBackend(ModelBackend):
    """
    Authenticate against django.contrib.auth.models.User using
    e-mail address instead of username.
    """
    def authenticate(self, username=None, password=None):
        try:
            user = User.objects.get(email__iexact = username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

В-четвертых, добавьте свой бэкэнд аутентификации в settings.py:

AUTHENTICATION_BACKENDS = ('mysite.backends.EmailAuthenticationBackend',)
2 голосов
/ 04 марта 2012

Вы можете просто использовать электронную почту в качестве имени пользователя, т. Е. Пользователи вводят свои электронные письма, а вы присваиваете их как атрибутам имени пользователя и электронной почты (или просто имя пользователя и оставляете адрес электронной почты пустым, в зависимости от того, что вам больше подходит).

Я использую такой подход на одном из сайтов, и он отлично работает. Он основан на django.contrib.auth, который, вероятно, является наиболее зрелым и распространенным решением, поэтому я постараюсь использовать это.

Библиотека, которую вы упомянули, довольно проста, но вводит некоторые настройки. То, что оно дает, может быть достигнуто тем, что я предложил Мое решение проще, их решение чище, и вам решать:)

1 голос
/ 04 марта 2012

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

class EmailAuthBackend(ModelBackend):
    '''Logs users using email addresses rather than usernames
    '''
    def authenticate(self, username=None, password=None):
        '''Try to log users on using any of their emails
        facebook does that too.
        username is an email address.
        '''
        try:
            email = Email.objects.get(email=username)
            user_profile = email.content_object
            if user_profile.user.check_password(password):
                return user_profile.user
        except Email.DoesNotExist:
            return None

Я также добавляю логин по номеру телефона, люди, очевидно, запоминают свои номера телефонов лучше, чем адреса электронной почты.так что вы могли бы заменить строку, которая говорит

email = Email.objects.get(email=username)

на

phone = Phone.objects.get(phone=username)

У меня обычно есть пользовательские бэкэнды аутентификации выше contrib, так что они могут работать как аварийное переключение при сбое этогоаутентифицировать.

AUTHENTICATION_BACKENDS = (
    # an email logon backend
    'account.backends.EmailAuthBackend',
    # django builtin auth will be diabled in the future
    'django.contrib.auth.backends.ModelBackend'
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...