Django自定义用户knox认证失败,authenticate返回None求助
问题根源与解决方案
核心问题:用户密码未正确加密
从你在Django Shell的测试结果可以明确:你能通过get_user_model().objects.get找到用户,但authenticate返回None,这说明用户密码是明文存储的,而Django的authenticate方法会使用加密后的密码进行校验,自然匹配失败,最终导致serializer.is_valid()返回False。
问题出在post_save信号的用户创建逻辑里:
get_user_model().objects.create(company=instance, username=instance.name, password=instance.password)
直接用create方法设置password字段会把明文密码存入数据库,而Django要求用户密码必须通过set_password()方法加密后存储。
修复步骤
1. 修正用户创建的信号逻辑
修改models.py中的信号接收器代码,改用set_password处理密码:
@receiver(post_save, sender=Company) def list_create(sender, instance=None, created=False, **kwargs): if created: # 先创建用户对象,不设置密码 user = get_user_model().objects.create(company=instance, username=instance.name) # 使用set_password加密密码后保存 user.set_password(instance.password) # 注意:需确保Company模型包含password字段 user.save()
补充:你的
Company模型代码里没有定义password字段,需要先添加该字段,否则instance.password会报错:class Company(m.Model): # ... 现有字段 password = m.CharField(max_length=128) # 添加密码字段
2. 更新现有用户的密码
对于已经创建的测试用户(比如CIEMSA),需要在Django Shell中手动更新密码:
>>> from django.contrib.auth import get_user_model >>> user = get_user_model().objects.get(username="CIEMSA") >>> user.set_password("225236Cm.") >>> user.save()
之后再测试authenticate,应该能正常返回用户对象:
>>> print(authenticate(username="CIEMSA", password="225236Cm.")) <MyUser: CIEMSA>
3. 验证视图逻辑
你的LoginAPI视图代码本身没有问题,修复密码加密后,serializer.is_valid()应该能正常通过,登录流程即可正常工作。
额外注意事项
- 永远不要直接明文存储用户密码,必须使用Django提供的
set_password()或create_user()方法(create_user会自动处理密码加密)。 - 若使用
create_user,信号逻辑也可以简化为:get_user_model().objects.create_user(company=instance, username=instance.name, password=instance.password)
内容的提问来源于stack exchange,提问作者Feijoes
相关产品推荐
相关产品推荐

