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

Django用户登录功能异常:正确凭证仍提示无效

Django登录失败:输入正确凭证仍提示无效的问题解决

你的登录失败问题根源在signup视图的密码处理逻辑错误,同时登录验证逻辑也存在匹配问题,具体问题和修复方案如下:

核心问题分析

  1. 重复哈希密码导致验证失败
    User.objects.create_user()方法会自动对传入的password参数进行哈希处理并存储,但你在创建用户后又调用了user.set_password(password),这会再次对原密码进行哈希,覆盖了正确的哈希值。最终数据库里存储的是二次哈希后的密码,登录时用原密码自然无法匹配。

  2. 登录时参数不匹配
    默认Django的authenticate()函数是根据username字段验证身份,但你注册时username和email是独立字段,登录时却把email传给了username参数,默认情况下无法找到对应用户。


修正后的代码

修复signup视图(解决密码哈希问题)

from django.db.models import Q
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login
from django.shortcuts import render

def signup(request):
    if request.method == 'POST':
        username = request.POST['username']
        email = request.POST['email']
        password = request.POST['password']
        confirm_password = request.POST['confirm_password']

        # 检查用户是否已存在
        if User.objects.filter(Q(username=username) | Q(email=email)).exists():
            return render(request, 'user_auth/signup.html', {'error_message': '用户名或邮箱已存在!'})
        
        # 检查密码是否匹配
        if password != confirm_password:
            return render(request, 'user_auth/signup.html', {'error_message': '两次输入的密码不一致!'})
        
        # create_user已自动处理密码哈希,无需额外调用set_password
        user = User.objects.create_user(username=username, email=email, password=password)
        return render(request, 'user_auth/signin.html')
    else:
        return render(request, 'user_auth/signup.html')

修复signin视图(两种可选方案)

方案1:临时适配——通过邮箱找用户再验证

def signin(request):
    if request.method == 'POST':
        email = request.POST['email']
        password = request.POST['password']
        
        try:
            # 先通过邮箱定位用户
            user = User.objects.get(email=email)
            # 用用户的真实username做认证
            user = authenticate(request, username=user.username, password=password)
            if user is not None:
                login(request, user)
                return render(request, 'user_auth/main.html')
        except User.DoesNotExist:
            pass
        
        return render(request, 'user_auth/signin.html', {'context': '邮箱和/或密码无效!'})
    return render(request, 'user_auth/signin.html')

方案2:长期优化——允许邮箱直接登录

如果希望用户可以直接用邮箱登录,推荐配置自定义认证后端:

  1. 在你的app下创建backends.py文件:
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
from django.db.models import Q

class EmailBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            # 支持用户名或邮箱登录
            user = User.objects.get(Q(username=username) | Q(email=username))
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None
  1. 在项目settings.py中添加配置:
AUTHENTICATION_BACKENDS = [
    '你的app名称.backends.EmailBackend',
    'django.contrib.auth.backends.ModelBackend',  # 保留默认用户名登录支持
]
  1. 此时signin视图可以保持原写法,无需修改:
def signin(request):
    if request.method == 'POST':
        email = request.POST['email']
        password = request.POST['password']
        user = authenticate(request, username=email, password=password)
        if user is not None:
            login(request, user)
            return render(request, 'user_auth/main.html')
        else:
            return render(request, 'user_auth/signin.html', {'context': '邮箱和/或密码无效!'})
    return render(request, 'user_auth/signin.html')

内容的提问来源于stack exchange,提问作者Mohammad Al Weis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:57:02