簡體   English   中英

在Django All Auth中使用多個登錄字段,電子郵件或電話號碼

[英]Using multiple login fields, email or phone number in Django All Auth

我正在使用Django All Auth對用戶進行身份驗證,但在登錄用戶時我需要使用電話號碼或電子郵件字段。 我擴展了用戶類,如下所示:

class User(AbstractUser):
    phone_number = models.CharField(max_length=10, unique=True)


    def __unicode__(self):
        return self.username 

我的注冊表單如下所示:

class SignupForm(forms.Form):
    phone_number = forms.CharField(max_length=10,label='phone_number')

    def signup(self, request, user):
        user.phone_number = self.cleaned_data['phone_number']
        user.save()

電話號碼使用此保存在后端,但如果用戶輸入電子郵件或電話號碼,我需要對用戶進行身份驗證。 我需要為Django All Auth擴展什么類。 我已經閱讀了很多問題,但找不到任何好的東西。

如果我在settings.py中放置ACCOUNT_USER_MODEL_USERNAME_FIELD ='phone_number',它會通過電話驗證,但不會通過電子郵件驗證。

編輯1:

我創建了一個文件backends.py,我編寫了這段代碼

class PhoneNumberBackend(object):
    """
    Custom Phone Number Backend to perform authentication via phone number
    """
    def authenticate(self, username=None, password=None):
        my_user_model = get_user_model()

        try:
            user = my_user_model.objects.get(phone_number=username)
            if user.check_password(password):
                return user # return user on valid credentials
        except my_user_model.DoesNotExist:
            return None # return None if custom user model does not exist 
        except:
            return None # return None in case of other exceptions

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

Settings.py現在看起來像這樣:

AUTHENTICATION_BACKENDS = (
    # 'userauth.backends.PhoneNumberBackend',
    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',

    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',

)

它應該使用電話號碼進行身份驗證,如果沒有,則應該回退到其他身份驗證方法,對吧? 它不像那樣工作。

首先,您需要在djagno中為此類電子郵件制作身份驗證后端

class EmailAuthentication(object):
def authenticate(self, request, username=None, password=None):
    try:
        user = User.objects.get(email=username)
        if user.check_password(password):
            return user
        return None
    except:
        return None
def get_user(self, user_id):
    try:
        return User.objects.get(id=user_id)
    except:
return None

您可以為電話號碼制作另一個電話號碼但確保在數據庫中使它們唯一,因此沒有人將擁有相同憑據的帳戶,您可以在表單干凈方法中再次檢查它,這是用於電子郵件

def clean_email(self):
    email = self.cleaned_data['email']
    if User.objects.filter(email=email).exists():
        raise forms.ValidationError(' user with this email is already registered -- Try loginigin or resting the password')    
    return email

然后你應該將auth后端放在設置文件中,不要忘記包含django的原始用戶名后端

AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'account.authentication.EmailAuthentication',
]

在之前的代碼中,我假設您的身份驗證后端位於帳戶應用程序中名為身份驗證的文件中

然后在視圖中,您將驗證用戶身份然后登錄

  username = form.cleaned_data['username']
  password = form.cleaned_data['password2']
  user = authenticate(username=username, password=password)
  if user:
      login(request, user)

或者您可以使用django.contrib.auth.views中的LoginView來簡化操作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM