Django 通过电子邮件地址而不是用户名进行用户注册和身份验证
我不想编写自定义的auth后端,我认为这样的常见任务一定已经由某个第三方应用程序解决了Django 通过电子邮件地址而不是用户名进行用户注册和身份验证,django,authentication,Django,Authentication,我不想编写自定义的auth后端,我认为这样的常见任务一定已经由某个第三方应用程序解决了 我在谷歌上搜索了一下,浏览了一下,但只找到了2008年的旧版本。是否已有其他备选方案?您可以将电子邮件用作用户名,即用户输入他们的电子邮件,然后您将其分配给用户名和电子邮件属性或JU用户名,并将电子邮件留空,以满足您的需要 我在其中一个网站上使用这种方法,效果很好。它基于django.contrib.auth,这可能是最成熟和最常见的解决方案,所以我会尝试使用它 您提到的库非常简单,但它引入了一些定制。它提供
我在谷歌上搜索了一下,浏览了一下,但只找到了2008年的旧版本。是否已有其他备选方案?您可以将电子邮件用作用户名,即用户输入他们的电子邮件,然后您将其分配给用户名和电子邮件属性或JU用户名,并将电子邮件留空,以满足您的需要 我在其中一个网站上使用这种方法,效果很好。它基于django.contrib.auth,这可能是最成熟和最常见的解决方案,所以我会尝试使用它
您提到的库非常简单,但它引入了一些定制。它提供的东西可能会通过我的提议实现。我的解决方案更简单,他们的解决方案更干净,这取决于您的决定:您可以将电子邮件用作用户名,即用户输入他们的电子邮件,然后您将其分配给用户名和电子邮件属性或JU用户名,并将电子邮件留空,以满足您的需要 我在其中一个网站上使用这种方法,效果很好。它基于django.contrib.auth,这可能是最成熟和最常见的解决方案,所以我会尝试使用它
您提到的库非常简单,但它引入了一些定制。它提供的东西可能会通过我的提议实现。我的解决方案更简单,他们的解决方案更干净,这取决于您的决定:您不需要为此使用应用程序。这是一个非常简单的方法。在我的项目中,每个用户都有一个配置文件,每个配置文件可以有多封电子邮件。用户可以使用其任何电子邮件地址登录系统
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)
与
我通常在contrib后端之上有定制的auth后端,因此当这个后端无法进行身份验证时,它可以作为故障转移
AUTHENTICATION_BACKENDS = (
# an email logon backend
'account.backends.EmailAuthBackend',
# django builtin auth will be diabled in the future
'django.contrib.auth.backends.ModelBackend'
)
你不需要使用应用程序。这是一个非常简单的方法。在我的项目中,每个用户都有一个配置文件,每个配置文件可以有多封电子邮件。用户可以使用其任何电子邮件地址登录系统
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)
与
我通常在contrib后端之上有定制的auth后端,因此当这个后端无法进行身份验证时,它可以作为故障转移
AUTHENTICATION_BACKENDS = (
# an email logon backend
'account.backends.EmailAuthBackend',
# django builtin auth will be diabled in the future
'django.contrib.auth.backends.ModelBackend'
)
你说,我不想编写定制的auth后端,但a正是Django希望你解决这个问题的方式,而且,它确实非常简单,比安装第三方应用简单得多 这里有一个简单的方法,用户有一个电子邮件地址,存储在内置用户对象的email字段中 首先,考虑区分大小写。尽管电子邮件地址的本地部分@符号之前的部分可能区分大小写,具体取决于电子邮件提供商,但Django的内置auth应用程序将电子邮件地址视为不区分大小写,例如,在决定响应密码重设请求向哪些用户发送电子邮件时。所以你最好也这样对待他们 其次,确保两个用户不能共享同一个电子邮件地址。您可以在数据库中手动执行此操作: ALTER TABLE auth_user添加唯一索引电子邮件; 或者,如果正在使用,则为调用的auth应用程序进行架构迁移 要强制执行不区分大小写的唯一性,您应该确保电子邮件字段的排序规则不区分大小写。我发现它已经是了,但你可以这样做: 更改表格auth_用户修改电子邮件VARCHAR75校对utf8_常规_ci; 或ascii\u general\u ci(如果您不支持) 第三,可能在mysite/backends.py中: 从django.contrib.auth.backends导入ModelBackend 从django.contrib.auth.models导入用户 类EmailAuthenticationBackendModelBackend: 使用对django.contrib.auth.models.User进行身份验证 电子邮件地址而不是用户名。 def authenticateself,用户名=无,密码=无: 尝试: user=user.objects.getemail\uuuu iexact=username 如果user.check\u密码: 返回用户 除User.DoesNotExist外: 一无所获 第四,将身份验证后端添加到settings.py:
你说,我不想编写定制的auth后端,但a正是Django希望你解决这个问题的方式,而且,它确实非常简单,比安装第三方应用简单得多 这里有一个简单的方法,用户有一个电子邮件地址,存储在内置用户对象的email字段中 < p> 首先,考虑区分大小写。尽管电子邮件地址的本地部分@符号之前的部分可能区分大小写,具体取决于电子邮件提供商,但Django的内置auth应用程序将电子邮件地址视为不区分大小写,例如,在决定响应密码重设请求向哪些用户发送电子邮件时。所以你最好也这样对待他们 其次,确保两个用户不能共享同一个电子邮件地址。您可以在数据库中手动执行此操作: ALTER TABLE auth_user添加唯一索引电子邮件; 或者,如果正在使用,则为调用的auth应用程序进行架构迁移 要强制执行不区分大小写的唯一性,您应该确保电子邮件字段的排序规则不区分大小写。我发现它已经是了,但你可以这样做: 更改表格auth_用户修改电子邮件VARCHAR75校对utf8_常规_ci; 或ascii\u general\u ci(如果您不支持) 第三,可能在mysite/backends.py中: 从django.contrib.auth.backends导入ModelBackend 从django.contrib.auth.models导入用户 类EmailAuthenticationBackendModelBackend: 使用对django.contrib.auth.models.User进行身份验证 电子邮件地址而不是用户名。 def authenticateself,用户名=无,密码=无: 尝试: user=user.objects.getemail\uuuu iexact=username 如果user.check\u密码: 返回用户 除User.DoesNotExist外: 一无所获 第四,将身份验证后端添加到settings.py:
你的方法很好,非常简单,我喜欢它,但有一个问题,因为用户名字段受max_length=30的限制,所以长电子邮件不适合。这个问题是否可以回避?是的,你可以看看你提到的应用程序的一部分。这将修改表以允许更长的电子邮件。我在我的产品数据库中做了类似的事情。对于开发,我认为这不会是一个问题…你的方法很好,非常简单,我喜欢它,但有一个问题,因为用户名字段受max_length=30的限制,所以长电子邮件不适合。这个问题是否可以回避?是的,你可以看看你提到的应用程序的一部分。这将修改表以允许更长的电子邮件。我在我的产品数据库中做了类似的事情。对于开发,我认为这不会是一个问题……EmailAuthBackend类上的get_user方法与它派生的ModelBackend类上的get_user方法相同。因此,您可以通过删除此方法简化代码。谢谢@GarethRees,我从项目中快速复制了代码。我记不起重写该方法时要添加哪些自定义操作。EmailAuthBackend类上的get_user方法与派生它的ModelBackend类上的get_user方法相同。因此,您可以通过删除此方法简化代码。谢谢@GarethRees,我从项目中快速复制了代码。我记不起在重写该方法时要添加哪些自定义操作。谢谢你,Gareth。现在我明白了。不过,还有一个问题。有没有办法在python代码中强制电子邮件的唯一性,例如在模型定义级别?如果您为用户配置文件定义自己的模型,而不是在auth应用程序中使用内置的用户模型,那么您可以在任何字段上设置unique=True。谢谢您,Gareth。现在我明白了。不过,还有一个问题。有没有一种方法可以强制python代码中电子邮件的唯一性,例如在模型定义级别?如果您为用户配置文件定义自己的模型,而不是在auth应用程序中使用内置的用户模型,则可以在任何字段上设置unique=True。