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

自定义Django认证后端异常:登录后仍跳转至登录页

Django自定义认证后端登录后request.user.is_authenticated无效问题

我实现了一个讲师登录用的自定义Django认证后端TutorAuthBackend,认证后端能正常返回有效用户对象,但使用@login_required装饰器时,检测到request.user.is_authenticated为None,导致无限登录循环。我尝试打印跨请求的session_key,结果一致;也调整了SESSION_COOKIE_AGE为7天,显式指定SESSION_ENGINE为django.contrib.sessions.backends.db,但问题仍未解决。在仪表盘视图中,request.user显示为AnonymousUser,request.user.is_authenticated()返回false。

相关代码:

from django.contrib.auth.backends import ModelBackend
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.contrib.auth import login
from django.contrib import messages
from django.shortcuts import render, redirect
from .models import Tutor

class TutorAuthBackend(ModelBackend):
    def authenticate(self, request, username_or_email=None, password=None, **kwargs):
        print(f"Attempting to authenticate: {username_or_email}")
        try:
            validate_email(username_or_email)
            is_valid_email_format = True
        except ValidationError:
            is_valid_email_format = False

        auth_type = 'email__iexact' if is_valid_email_format else 'username__iexact'
        auth_param = {auth_type: username_or_email}

        try:
            tutor = Tutor.objects.get(**auth_param)
            if tutor.check_password(password):
                print(f"Authenticated: {tutor}")
                return tutor
        except Tutor.DoesNotExist:
            pass

        return None

    def get_user(self, user_id):
        """
        Returns the tutor object using the given user_id.
        """
        try:
            return Tutor.objects.get(pk=user_id)
        except Tutor.DoesNotExist:
            return None


def tutor_login(request):
    if request.method == 'POST':
        username_or_email = request.POST.get('username_or_email')
        password = request.POST.get('password')
        tutor = TutorAuthBackend().authenticate(request, username_or_email=username_or_email, password=password)
        if tutor:
            login(request, tutor, backend='tutor.backends.TutorAuthBackend')
            messages.success(request, "You're Logged In")
            if tutor.profile_picture:
                print("Profile Picture:", tutor.profile_picture.url)
                return redirect('tutor_dashboard', tutor_id=tutor.id)
            return redirect('tutor_profile')
        else:
            tutor_exists = Tutor.objects.filter(username=username_or_email).exists()
            if tutor_exists:
                messages.error(request, 'Incorrect Password')
            else:
                messages.error(request, 'User Not Found')
            return render(request, 'tutor/tutor_login.html', context={'username_or_email': username_or_email})
    else:
        return render(request, 'tutor/tutor_login.html')

排查与解决方法

1. 确认自定义用户模型配置

如果Tutor是作为自定义用户模型使用,必须:

  • 继承AbstractBaseUser和PermissionsMixin
  • 在settings.py中设置AUTH_USER_MODEL = 'tutor.Tutor'(替换为你的app名和模型名)
    如果Tutor只是普通模型而非用户模型,Django认证系统无法将其识别为合法用户,会导致登录后仍为AnonymousUser。

2. 添加认证后端到配置

在settings.py中配置认证后端列表,确保你的自定义后端被包含:

AUTHENTICATION_BACKENDS = [
    'tutor.backends.TutorAuthBackend',
    'django.contrib.auth.backends.ModelBackend',  # 可选,保留默认后端兼容
]

3. 修正is_authenticated的调用方式

Django 1.10+版本中,is_authenticated是只读属性,不是方法。原代码中request.user.is_authenticated()的写法会返回False(因为调用了不存在的方法),正确写法是request.user.is_authenticated(无括号)。

4. 验证后端路径正确性

确保login函数中指定的后端路径'tutor.backends.TutorAuthBackend'与实际文件路径一致。比如你的后端文件是tutor/backends.py,这个路径就是正确的;如果文件结构不同,需对应调整。

5. 检查用户模型必要属性

自定义用户模型Tutor必须包含:

  • USERNAME_FIELD(指定唯一标识字段,比如username或email)
  • is_active属性(默认应为True,否则用户会被视为无效)
  • 继承AbstractBaseUser会自动获得check_password等必要方法

6. 调试会话状态

在登录视图和仪表盘视图中添加调试代码,确认会话和用户身份:

# 登录视图login后添加
print(f"登录后用户: {request.user}, 认证状态: {request.user.is_authenticated}")
print(f"会话key: {request.session.session_key}")

# 仪表盘视图开头添加
print(f"仪表盘请求用户: {request.user}, 认证状态: {request.user.is_authenticated}")
print(f"会话key: {request.session.session_key}")

如果会话key一致但用户身份未被识别,基本可以确定是用户模型未被Django认证系统正确识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:40:58