英文:
Django Custom Authentication Backend does not work
问题
这是你提供的代码的中文翻译:
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="手机号码 / 电子邮件")
    password = forms.CharField(widget=forms.PasswordInput(), label="密码")
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, "登录成功。", "success")
                return redirect("home:home")
            else:
                messages.error(request, "用户名和/或密码错误。", "danger")
                return render(request, self.template_name, {"form": form})
        messages.error(request, "登录失败", "danger")
        return render(request, self.template_name, {"form": form})
settings.py:
AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    "accounts.authentication.CustomAuthBackend",
]
注意:我已经根据您提供的代码进行了翻译,没有包括任何额外的内容。
英文:
I've made a user model with USERNAME_FIELD defined as phone_number. So login form requires phone_number and password. I want users to be able to also login through their emails. So I created an authentication backend class. Users can login with their phone numbers but they canbot do so with their emails and will receive the 'Username and/or password is wrong' message.
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",
]
答案1
得分: 1
我忘了在authenticate方法的参数中包括request。 ![]()
正确版本:
def authenticate(self, request, username=None, password=None):
    # ...
英文:
I had forgotten to include request as a parameter in authenticate method. ![]()
Correct version:
def authenticate(self, request, username=None, password=None):
    # ...
答案2
得分: 0
假设您已经在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()
        # 检查用户名是电子邮件地址还是电话号码
        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
这是给定代码段的翻译部分,不包括代码本身。
英文:
Assuming that you have already included the custom backend in AUTHENTICATION_BACKENDS setting in settings.py file.
You can make a condition check that whether it is a phone no. or email using regex so:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论