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

huangapple go评论51阅读模式
英文:

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方法的参数中包括requestDjango自定义身份验证后端不起作用
正确版本:

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

I had forgotten to include request as a parameter in authenticate method. Django自定义身份验证后端不起作用
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

huangapple
  • 本文由 发表于 2023年2月16日 03:01:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75464360.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定