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

Django自定义后端登录异常:认证成功但未实际登录

Django自定义认证后端登录成功但用户未实际登录的修复方案

你的问题出在三个核心地方:自定义User模型的配置缺失、认证后端方法缩进错误、密码字段重复定义导致验证失效,以下是分步修复:

1. 修正自定义User模型

继承AbstractBaseUser必须指定USERNAME_FIELD(用于认证的唯一标识字段),且不需要重复定义password、last_login这些父类已有的字段——你自己定义的password是明文存储,会导致check_password验证永远失败。另外last_login需要用DateTimeField而非DateField,否则Django更新登录时间时会出错。

修正后的models.py:

from django.contrib.auth.models import AbstractBaseUser

class User(AbstractBaseUser):
    id = models.AutoField(primary_key=True)
    username = models.TextField(unique=True)  # 认证字段需保证唯一
    real_name = models.TextField()
    email = models.TextField()
    description = models.TextField()
    created_at = models.DateField(auto_now_add=True)  # 自动设置创建时间
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)

    # 必须指定的认证字段
    USERNAME_FIELD = 'username'
    # 超级用户创建时必填字段(可选配置)
    REQUIRED_FIELDS = ['email']

    class Meta:
        managed = False
        db_table = 'user'
        
    def __str__(self) -> str:
        return self.username

2. 修复认证后端的方法缩进

你的UserBackend中get_user方法缩进错误,被嵌套在authenticate方法内部,导致Django无法调用该方法验证登录状态。需要将get_user移到authenticate同级:

修正后的backends.py:

from django.contrib.auth.backends import ModelBackend
from .models import User

class UserBackend(ModelBackend):
    def authenticate(self, **kwargs):
        username = kwargs.get('username')
        password = kwargs.get('password')

        if not username or not password:
            return None
            
        try:
            user_ = User.objects.get(username=username)
            if user_.check_password(password):
                return user_
        except User.DoesNotExist:
            return None

    # 移到authenticate方法外部,保持同级缩进
    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

3. 优化视图中的认证逻辑

不需要手动实例化UserBackend,直接使用Django内置的auth.authenticate,前提是在settings.py中配置你的认证后端:

# settings.py添加配置
AUTHENTICATION_BACKENDS = [
    'core.backends.UserBackend',
]

修正后的signin视图:

from django.contrib.auth import authenticate, login
from django.shortcuts import redirect, render
from django.contrib import messages

def signin(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']

        # 使用内置authenticate,自动调用配置的后端
        user = authenticate(request, username=username, password=password)

        if user is not None:
            login(request, user)
            print('Logged In')
            # 优先跳转到next参数,否则回到首页
            next_url = request.GET.get('next', '/')
            return redirect(next_url)
        else:
            messages.info(request, 'Invalid Username or Password! Try again')
            return redirect("signin")
    return render(request,'signin.html')

验证步骤

  1. 确保PostgreSQL中的user表密码字段是Django加密后的格式(如果之前是明文,需通过Django shell执行user.set_password('新密码')后保存)
  2. 重启Django服务,重新测试登录

内容的提问来源于stack exchange,提问作者Dirky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:40:54