Django项目中authenticate函数始终返回None的问题求助
车辆项目管理系统登录认证问题
我正在开发一个车辆项目管理系统,使用MySQL自定义表存储用户注册信息。用户登录时,authenticate函数始终返回None,登录采用邮箱和密码字段。已完成以下排查:
- 确认数据库取值正常;
- 检查后端认证逻辑。
测试时执行testuser = authenticate(username='sim@example.com', password='sim')返回None,打印数据库数据显示能获取到邮箱vim@gmail.com和密码vim,但authenticate仍返回None。
相关代码如下:
UserProfiles模型
class UserProfiles(models.Model): full_name=models.CharField(max_length=200) phone_number=models.IntegerField() email=models.CharField(unique=True,max_length=20) password=models.CharField(max_length=200) # is_active = models.BooleanField(default=True) # is_staff = models.BooleanField(default=False) USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['full_name', 'phone_number'] def set_password(self, password): self.password = make_password(password) def check_password(self, password): return check_password(password, self.password)
userLogin视图函数
def userLogin(request): if request.method == 'POST': email = request.POST.get('email') password = request.POST.get('password') print('from loginhtml page',email,password) try: user_profile = UserProfiles.objects.get(email=email) user = authenticate(request, username=email, password=password) print("from database ",user_profile.email,user_profile.password) print(user) if user is not None: login(request, user) messages.success(request, 'You have been logged in successfully.') return redirect('/DashboardPage.html') else: error_message='Invalid email or password. Please try again.' messages.error(request, error_message) except UserProfiles.DoesNotExist: error_message='Invalid email or password. Please try again.' messages.error(request, error_message) return render(request, 'userLogin.html')
自定义认证后端UserProfileBackend
from django.contrib.auth.backends import BaseBackend from django.contrib.auth import get_user_model from django.shortcuts import redirect from .models import UserProfiles class UserProfileBackend(BaseBackend): def authenticate(self, request, email=None, password=None): try: user = UserProfiles.objects.get(email=email) if user.check_password(password): return user except UserProfiles.DoesNotExist: return None
登录页面模板
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Vehicle Parking Management System - User Login</title> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="{% static 'styles/loginstyle.css' %} "> </head> <body> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <a class="navbar-brand text-primary" href="#">Vehicle Parking Management System</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> </nav> <div class="container mt-5"> <h1 class="text-center mb-5"><em><strong>Welcome to the Vehicle Parking Management System</strong></em></h1> <div class="row"> <div class="col-md-6 offset-md-3"> <div class="card"> <div class="card-body"> <h5 class="card-title text-center">User Login</h5> <form action="{% url 'parkingapp:userLogin' %}" method="POST"> {% csrf_token %} <div class="form-group"> <label for="email">Email Address</label> <input type="email" class="form-control" id="email" name='email' placeholder="Enter your email address"> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" class="form-control" id="password" name="password" placeholder="Enter your password"> </div> {% if messages %} <ul class="messages"> {% for message in messages %} <li>{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> {% endfor %} </ul> {% endif %} <button type="submit" class="btn btn-primary btn-block">Login</button> </form> <div class="text-center"> <p class="text-center">Don't have an existing account? <a href="{% url 'parkingapp:userSignup' %}" class="btn btn-link">Sign up here</a></p> </div> </div> </div> </div> </div> </div> </div> <script src="{% static 'js/loginscript.js' %}"></script> </body> </html>
问题分析与解决方案
未配置自定义认证后端
Django默认不会自动加载自定义认证后端,需在settings.py中添加配置:AUTHENTICATION_BACKENDS = [ 'your_app_name.backends.UserProfileBackend', # 替换为你的后端文件路径 'django.contrib.auth.backends.ModelBackend', # 可选,保留默认后端 ]认证参数不匹配
视图中调用authenticate时传入的是username参数,但自定义后端的authenticate方法接收的是email参数,修改后端方法兼容:def authenticate(self, request, username=None, password=None): try: user = UserProfiles.objects.get(email=username) if user.check_password(password): return user except UserProfiles.DoesNotExist: return None密码未正确哈希存储
检查注册逻辑是否调用了set_password方法哈希密码,若直接存储明文,check_password会验证失败。示例注册逻辑:def userSignup(request): if request.method == 'POST': user = UserProfiles( full_name=request.POST.get('full_name'), phone_number=request.POST.get('phone_number'), email=request.POST.get('email') ) user.set_password(request.POST.get('password')) # 必须调用此方法哈希密码 user.save() # 后续跳转或提示逻辑模型缺少认证必要字段
取消注释模型中的is_active和is_staff字段,Django认证系统依赖这些字段判断用户状态:is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False)模型继承问题
自定义用户模型建议继承AbstractBaseUser和PermissionsMixin,确保兼容Django认证体系:from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin class UserProfiles(AbstractBaseUser, PermissionsMixin): full_name=models.CharField(max_length=200) phone_number=models.IntegerField() email=models.CharField(unique=True,max_length=20) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['full_name', 'phone_number'] # 可移除自定义的set_password和check_password,AbstractBaseUser已实现相关逻辑
内容的提问来源于stack exchange,提问作者Raseena Anwar
相关产品推荐
相关产品推荐

