Django allauth用电子邮件作为用户名和多个站点

bod*_*ger 9 django django-sites django-allauth

在多个站点上使用时,是否可以将Django allauth的身份验证方法设置为"email"?

我的目标是允许拥有电子邮件地址bob@example.com的用户在site1.com上创建一个帐户,并在site2.com上创建一个单独的帐户.

为了使用电子邮件身份验证,我需要在设置中将UNIQUE_EMAIL设置为True,但这会阻止已在一个站点中拥有帐户的用户在其他站点中创建帐户.

rti*_*dru 3

我假设您希望允许为 Django 设置中的每个站点单独注册相同的电子邮件。

查看 allauth 代码;目前看来这样做是不可行的,可能是因为 allauth 没有将站点 ID 作为用户注册过程的一部分考虑在内。

class AppSettings(object):

    class AuthenticationMethod:
        USERNAME = 'username'
        EMAIL = 'email'
        USERNAME_EMAIL = 'username_email'

    class EmailVerificationMethod:
        # After signing up, keep the user account inactive until the email
        # address is verified
        MANDATORY = 'mandatory'
        # Allow login with unverified e-mail (e-mail verification is
        # still sent)
        OPTIONAL = 'optional'
        # Don't send e-mail verification mails during signup
        NONE = 'none'

    def __init__(self, prefix):
        self.prefix = prefix
        # If login is by email, email must be required
        assert (not self.AUTHENTICATION_METHOD ==
                self.AuthenticationMethod.EMAIL) or self.EMAIL_REQUIRED
        # If login includes email, login must be unique
        assert (self.AUTHENTICATION_METHOD ==
                self.AuthenticationMethod.USERNAME) or self.UNIQUE_EMAIL
Run Code Online (Sandbox Code Playgroud)

一种方法如下: - 将 allauth 保留AUTHENTICATION_METHOD为用户名 - 将站点与用户信息一起存储,可能在用户配置文件中或通过覆盖用户模型来存储。Email- 使和的组合Site独一无二。- 覆盖LoginView用户输入电子邮件的内容;Email您可以将,的组合转换Site为唯一用户帐户和用户名;您可以将其传递给 allauth 来执行登录。

假设您使用站点框架;你的代码看起来像这样:

from allauth.account.views import LoginView
from django.core.exceptions import ObjectDoesNotExist


class CustomLoginView(LoginView):

    def get_user():
        email = request.POST.get('email')
        current_site = Site.objects.get_current()
        try:
            user = User.objects.get(email=email, site=current_site)
        except ObjectDoesNotExist:
            pass  # Handle Error: Perhaps redirect to signup 
        return user


    def dispatch(self, request, *args, **kwargs):
        user = self.get_user()
        request.POST = request.POST.copy()
        request.POST['username'] = user.username
        return super(CustomLoginView, self).dispatch(request, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

然后使用自定义登录视图对 LoginView 进行猴子修补:

allauth.account.views.LoginView = CustomLoginView

有关设置 Site FK 和自定义身份验证后端的相关阅读:

  • 这个方法确实有效,但它需要比上面更多的努力。allauth 代码中有相当多的地方过滤电子邮件地址,但没有(显然)考虑网站,因此需要重写很多方法,但我并不完全相信这是正确的做法。然而,在没有得到 allauth 人任何回应的情况下,我认为这是唯一真正的选择。 (2认同)