首页 > 解决方案 > django 中的自定义身份验证不起作用

问题描述

我是 django 的新手,我想对用户进行身份验证emailusername因此password我编写了一个自定义身份验证,如文档中所示,但它似乎没有被调用,我不知道我该怎么做?

设置.py

AUTHENTICATION_BACKENDS = ('accounts.backend.AuthBackend',)

视图.py

def login(request):
    if request.method == 'POST':
        username_or_email = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username_or_email, password=password)
        print(user)
        if user is not None:
            return reverse('task:home')
        else:
            messages.error(request, "Username or password is invalid")
            return render(request, 'accounts/login.html')
    else:
         return render(request, 'accounts/login.html')

后端.py

from django.contrib.auth.models import User
from django.db.models import Q


class AuthBackend(object):
    supports_object_permissions = True
    supports_anonymous_user = False
    supports_inactive_user = False

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

    def authenticate(self, username, password):
        print('inside custom auth')
        try:
            user = User.objects.get(
                Q(username=username) | Q(email=username) )
            print(user)
        except User.DoesNotExist:
            return None
        print(user)
        if user.check_password(password):
             return user
        else:
            return None

我在课堂上写了这些print语句,以检查它们是否被调用并在控制台中编写。但是,它们没有被打印出来,并且打印出来的print声明views.pyNone

标签: djangopython-3.xdjango-authentication

解决方案


你需要extendModelBackenddjango.contrib.auth.backends

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend

User = get_user_model()

class AuthBackend(ModelBackend):
    supports_object_permissions = True
    supports_anonymous_user = False
    supports_inactive_user = False

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

    def authenticate(self, request, username=None, password=None):
        print('inside custom auth')
        try:
            user = User.objects.get(
                Q(username=username) | Q(email=username) )
            print(user)
        except User.DoesNotExist:
            return None
        print(user)
        if user.check_password(password):
             return user
        else:
            return None

并且settings.py不要忘记添加您的自定义后端身份验证

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'accounts.backend.AuthBackend'
]

另一种可能的解决方案

从您的代码中,我看到的是您希望您email应该将其视为User模型的用户名。您可以轻松修改Django's AbstructUser模型,如下所示

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
      # your necessary additional fields 
       USERNAME_FIELD = 'email'  # add this line 

现在email字段将被视为 user_name 字段。无需添加自定义authentication-backend


推荐阅读