Django普通用户认证失败求助:仅超级用户可正常登录
问题根源分析
- 密码未哈希存储:注册视图
register中直接给User实例的password赋值明文密码,而Django的authenticate方法仅能验证哈希后的密码。超级用户通过createsuperuser命令创建,该命令会调用自定义管理器中的set_password自动哈希密码,因此能正常认证;普通用户密码以明文存储,无法通过校验。 - 重复定义password字段:自定义
User模型继承了AbstractUser,父类已内置password字段,重复定义会干扰Django的密码哈希逻辑。 - Admin注册顺序错误:
admin.py中先注册User模型再定义UserAdmin,导致自定义Admin配置未生效。
解决方案
1. 修复注册视图的密码处理
修改views.py中的register函数,使用set_password方法哈希密码:
def register(request): if request.method == "POST": username = request.POST.get("username") email = request.POST.get("email") password = request.POST.get("password") phone_number = request.POST.get("phone_number") user = User( username=username, email=email, phone_number=phone_number ) user.set_password(password) # 关键:对密码进行哈希处理 user.save() return redirect('main:index') return render(request, 'users/register.html')
2. 移除模型中重复的password字段
修改models.py,删除自定义的password字段:
class User(AbstractUser): username = models.CharField(max_length=20, unique=True) email = models.EmailField(unique=True) # 移除该行,AbstractUser已包含password字段 # password = models.CharField(null=True, blank=False, max_length=30) phone_number = PhoneNumberField(region="IN", unique=True, null=True, blank=False) USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username'] objects = CustomUserManager() def __str__(self): return self.username
3. 修正Admin注册顺序
修改admin.py,先定义UserAdmin再注册模型:
from django.contrib import admin from .models import User class UserAdmin(admin.ModelAdmin): list_display = ('id', 'username', 'email') # 新增email字段便于后台查看 admin.site.register(User, UserAdmin) # 先传入模型,再传入Admin配置类
4. 重置现有普通用户密码(可选)
之前注册的普通用户密码为明文存储,需重置后才能登录,可通过Django Shell执行:
from users.models import User user = User.objects.get(email='目标用户邮箱') user.set_password('新密码') user.save()
验证修复
完成上述修改后:
- 新注册的普通用户密码会被正确哈希存储
- 使用邮箱和密码登录时,
authenticate方法可正常验证 - 超级用户依然能正常登录
内容的提问来源于stack exchange,提问作者engle23
相关产品推荐
相关产品推荐

