You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django认证报错:check_password()缺少必填位置参数'encoded'

问题描述

使用自定义用户模型(AbstractBaseUser)和邮箱认证后端时,通过python manage.py shell创建的用户(密码格式为pbkdf2_sha256$390000$------------------------$-)在认证时抛出错误:

TypeError: check_password() missing 1 required positional argument: 'encoded'
相关代码

settings.py

AUTH_USER_MODEL = 'accounts.Usermanagement'

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

backends.py

# from django.contrib.auth.models import User
from django.contrib.auth.hashers import check_password
from django.contrib.auth import get_user_model

Usermanagement = get_user_model()

class EmailAuthBackend:
    def authenticate(self,request,username,password):
        print("Custom authenticate rqst: ",request)
        try:
            user = Usermanagement.objects.get(emailid=username)
            # print(password)
            # print(user.password)
            # print(check_password(password))
            # print(user.check_password(password))
            if user.password == password or user.password == check_password(password): #! PROBLEM
                return user
            return None
            
        except user.DoesNotExist:
            return None
    
    def get_user(self,user_id): 
        try:
            return Usermanagement.objects.get(pk=user_id)
        except Usermanagement.DoesNotExist:
            return None

managers.py

from django.contrib.auth.models import BaseUserManager
from django.contrib.auth.hashers import make_password

class UsermanagementCustomUserManager(BaseUserManager):
    # create_user(username_field, password=None, **other_fields)
    def create_user(self,emailid,roleid,organizationid,firstname, password=None,
                    passwordexpirydate="2022-12-12 12:00:00",createdby=0,modifiedby=0):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not emailid:
            raise ValueError('Users must have an email address')

        user = self.model(
            emailid=self.normalize_email(emailid),
            roleid = roleid,
            organizationid=organizationid,
            firstname = firstname,
            password= make_password(password),
            createdby = createdby,
            modifiedby = modifiedby,
        )

views.py

from django.contrib import messages
from django.http import HttpResponse

from django.contrib.auth import get_user_model

# Check
from django.conf import settings
print("auth backend",settings.AUTHENTICATION_BACKENDS)

# Check
# print(get_user_model())

def loginPage(request):
    # POST
    if request.method == 'POST':
        form = AuthenticationForm(request,data=request.POST)

        if form.is_valid(): # Form Valid
            email = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            #Check
            print("EMAIL: ",email)
            print("PASSWORD: ",password)
            # Authentication USER
            user = authenticate(request,username=email,password=password)
            print("Authenticated ",user) # Check
            # check
            print(user)

            if user is not None: # If User found
                login(request,user)
                # messages.info(request, f"You are now logged in as {email}.")
                return redirect ('inquiries')

            else: # If User Not found
                messages.error(request,"User not found")
                return HttpResponse("User not found, not able to login")

        else: # Form InValid
            messages.error(request,"Invalid username or password.")
            return HttpResponse("Form Invalid")
    # GET
    else:
        form = AuthenticationForm()
        context = {"form":form}
        return render(request,"loginpage.html",context=context)
解决方案

错误点说明

  1. check_password调用参数缺失:该函数需要传入两个参数(明文密码、数据库加密密码),原代码只传了一个,导致报错。
  2. 密码校验逻辑错误:直接用明文密码和加密后的数据库密码对比,永远不会相等,完全没必要。
  3. 异常捕获对象错误:except user.DoesNotExist中的user是实例对象,应该用模型类Usermanagement.DoesNotExist。

修正后的backends.py

from django.contrib.auth.hashers import check_password
from django.contrib.auth import get_user_model

Usermanagement = get_user_model()

class EmailAuthBackend:
    def authenticate(self, request, username, password):
        print("Custom authenticate rqst: ", request)
        try:
            user = Usermanagement.objects.get(emailid=username)
            # 直接使用AbstractBaseUser自带的check_password方法,内部已封装哈希校验逻辑
            if user.check_password(password):
                return user
            return None
            
        except Usermanagement.DoesNotExist:
            return None
    
    def get_user(self, user_id): 
        try:
            return Usermanagement.objects.get(pk=user_id)
        except Usermanagement.DoesNotExist:
            return None

额外提示

  • 自定义用户模型必须继承AbstractBaseUser,才能拥有check_password等内置的密码处理方法。
  • 不要手动编写密码哈希对比逻辑,用框架提供的方法更安全可靠。

内容的提问来源于stack exchange,提问作者Nipun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 21:25:24