Django自定义身份验证后端不工作

ijxebb2r  于 2023-02-17  发布在  Go
关注(0)|答案(2)|浏览(123)

我做了一个用户模型,USERNAME_FIELD定义为phone_number。所以登录表单需要phone_numberpassword。我希望用户也能通过他们的电子邮件登录。所以我创建了一个身份验证后端类。用户可以用他们的电话号码登录,但他们不能用他们的电子邮件登录,并会收到“用户名和/或密码错误”的消息。
authentication.py:

from django.contrib.auth import get_user_model

class CustomAuthBackend:
    def authenticate(self, username=None, password=None):
        try:
            user = get_user_model().objects.get(email=username)
            if password:
                if user.check_password(password):
                    return user
            return None
        except:
            return None

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

forms.py:

class UserLoginForm(forms.Form):
    username = forms.CharField(label="Phone Number / Email")
    password = forms.CharField(widget=forms.PasswordInput(), label="Password")

views.py:

class UserLogin(View):
    form_class = UserLoginForm
    template_name = "accounts/login.html"

    def get(self, request):
        return render(request, self.template_name, {"form": self.form_class})

    def post(self, request):
        form = self.form_class(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            user = authenticate(
                request, username=cd["username"], password=cd["password"]
            )
            if user:
                login(request, user)
                messages.success(request, "Logged in successfully.", "success")
                return redirect("home:home")
            else:
                messages.error(request, "Username and/or password is wrong.", "danger")
                return render(request, self.template_name, {"form": form})
        messages.error(request, "Login failed", "danger")
        return render(request, self.template_name, {"form": form})

settings.py:

AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    "accounts.authentication.CustomAuthBackend",
]
5ssjco0h

5ssjco0h1#

假设您已经在settings.py文件的AUTHENTICATION_BACKENDS设置中包含了自定义后端。
您可以使用regex条件检查是电话号码还是电子邮件,因此:

import re
from django.contrib.auth import get_user_model

class CustomAuthBackend:
    def authenticate(self, request, username=None, password=None):
        UserModel = get_user_model()

        # Check whether username is an email address or phone number
        if re.match(r'^\+?\d{10,14}$', username):
            try:
                user = UserModel.objects.get(phone_number=username)
                if user.check_password(password):
                    return user
            except UserModel.DoesNotExist:
                return None
        else:
            try:
                user = UserModel.objects.get(email=username)
                if user.check_password(password):
                    return user
            except UserModel.DoesNotExist:
                return None

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

i7uaboj42#

我忘了在authenticate方法中包含request作为参数。:)正确版本:

def authenticate(self, request, username=None, password=None):
    # ...

相关问题