用户注册和通过电子邮件地址而不是用户名进行身份验证

Moo*_*ker 1 authentication django

我不想编写自定义身份验证后端,我认为这样的常见任务必须已经由一些第三方应用程序解决.

我做了一些谷歌搜索和略读,但发现只有https://bitbucket.org/hakanw/django-email-usernames/wiki/Home这是相当老(2008年).还有其他替代品吗?

Gar*_*ees 7

你说,"我不想编写自定义身份验证后端"但是自定义身份验证后端正是Django期望你解决这个问题的方式,而且,它真的很简单 - 比安装第三方应用程序简单得多.

这是一种简单的方法,其中用户有一个电子邮件地址,存储在email内置User对象的字段中.

首先,考虑区分大小写.即使电子邮件地址的本地部分(@符号前面的部分)可能区分大小写(取决于电子邮件提供商),Django的内置auth应用程序将电子邮件地址视为不区分大小写(例如,在决定响应密码重置请求时向哪些用户发送电子邮件时).所以你最好也可以这样对待它们.

其次,确保两个用户不能共享同一个电子邮件地址.您可以在数据库中手动执行此操作:

ALTER TABLE auth_user ADD UNIQUE INDEX (email);
Run Code Online (Sandbox Code Playgroud)

或者如果您使用的是South,则为auth您调用的应用程序进行架构迁移db.create_unique('auth_user', 'email').

要强制使用不区分大小写的唯一性,应确保email字段上的排序规则不区分大小写.我发现它已经存在了,但你可能会这样做:

ALTER TABLE auth_user MODIFY email VARCHAR(75) COLLATE utf8_general_ci;
Run Code Online (Sandbox Code Playgroud)

(或者,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
Run Code Online (Sandbox Code Playgroud)

第四,将您的身份验证后端添加到您的settings.py:

AUTHENTICATION_BACKENDS = ('mysite.backends.EmailAuthenticationBackend',)
Run Code Online (Sandbox Code Playgroud)