Django登录authenticate仅超级用户生效普通用户返回None问题
问题相关代码
Views.py
def Tourist_login(request): if request.method == 'POST': form = Tourist_login_form(request.POST) if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password'] user = authenticate(username=username,password=password) print(user) if user is not None: login(request,user) messages.success(request,'logged in') return redirect('home') else: messages.error(request,"Invalid login credentials!") return redirect('touristlogin') else: return redirect('touirstlogin') else: form = Tourist_login_form() return render(request,'accounts/tourist_login.html',{'form':form})
故障现象
调用authenticate()认证函数时固定返回None:使用超级用户账号密码通过表单提交可正常完成登录流程,但普通用户提交账号密码始终无法通过认证,仅超级用户凭证可被正常校验,普通用户提交的登录信息无法完成认证。
故障根因及修复方案
按出现概率从高到低排查:
- 普通用户密码未做哈希加密
这是该问题最高发的原因:如果创建普通用户时直接调用User.objects.create(username=xxx, password=明文密码),密码会以明文形式存入数据库,而authenticate()函数会对传入的密码做哈希运算后和数据库存储的哈希值比对,明文密码必然校验失败。超级用户一般通过python manage.py createsuperuser命令创建,创建流程自动对密码做哈希处理,因此可以正常登录。
修复方式:- 后续创建普通用户必须使用Django内置的
create_user方法,自动完成密码哈希:
from django.contrib.auth import get_user_model User = get_user_model() # 正确创建用户的方式 User.objects.create_user(username="普通用户账号", password="用户密码")- 对已经创建的明文密码普通用户,手动执行密码哈希重置:
# 找到对应用户 user = User.objects.get(username="要修复的普通用户名") # 重置密码,自动做哈希处理 user.set_password("该用户的正确密码") user.save() - 后续创建普通用户必须使用Django内置的
- 普通用户账号未激活
Django默认的ModelBackend认证后端会直接拦截is_active字段为False的用户,直接返回None,不会走后续密码校验流程。超级用户创建时默认is_active=True,如果普通用户创建时未手动设置该字段为True,就会出现认证失败。
修复方式:
进入Django shell查询并修改用户状态:from django.contrib.auth import get_user_model User = get_user_model() user = User.objects.get(username="要检查的普通用户名") # 打印激活状态,如果返回False则执行修改 print(user.is_active) user.is_active = True user.save() - 自定义认证后端添加了超级用户限制
如果项目在settings.py中配置了自定义的AUTHENTICATION_BACKENDS,检查自定义认证类的逻辑,确认不存在if not user.is_superuser: return None这类仅放行超级用户的判断分支,如果有则删除对应限制逻辑即可。 - 表单参数传递异常
打印form.cleaned_data中获取到的username、password值,确认和数据库存储的用户信息一致,排查表单是否对输入内容做了额外的截断、转义处理,导致传入authenticate()的参数和实际存储值不匹配。
额外提示:代码中表单校验失败分支的跳转地址'touirstlogin'存在拼写错误,和正常跳转的'touristlogin'不一致,建议同步修正,避免表单校验出错时出现404问题。
内容的提问来源于stack exchange,提问作者Rishi Gupta
相关产品推荐
相关产品推荐

