Django中request.user.is_authenticated何时为真?多登录限制信号不触发求助
解决方案
1 信号未触发问题修复
- 首先检查
settings.py中INSTALLED_APPS配置:确保你注册的是accounts.apps.AccountsConfig,而非单纯的accounts,否则自定义AppConfig的ready方法不会执行,信号不会完成注册。 - 删除信号重复注册逻辑:你同时使用了
@receiver装饰器和user_logged_in.connect手动绑定,二者功能重复,删掉手动绑定的代码即可。 - 修正信号内的字段参数错误:你的
LoggedInUser模型中关联Session的字段名为session_key,且为外键类型,不能直接传入session字符串,需要传入Session实例,修正后的信号代码如下:
from django.contrib.auth.signals import user_logged_in from django.contrib.sessions.models import Session from django.dispatch import receiver from .models import LoggedInUser @receiver(user_logged_in) def delete_other_active_sessions(sender, user, request, **kwargs): # 删除该用户所有历史登录会话 Session.objects.filter(logged_in_user__user=user).delete() # 保存当前会话确保生成有效session_key request.session.save() # 获取当前会话的实例对象 current_session = Session.objects.get(session_key=request.session.session_key) # 绑定当前用户和会话 LoggedInUser.objects.get_or_create(user=user, session_key=current_session)
- 确认登录逻辑调用了Django自带的登录方法:
user_logged_in信号只有在调用django.contrib.auth.login(request, user)时才会自动触发,如果你使用的是自定义登录、JWT/Token等无会话登录逻辑,没有调用原生login方法,需要手动触发信号,在你的登录逻辑中加入如下代码即可:
from django.contrib.auth.signals import user_logged_in # 你自己的登录校验逻辑完成后添加 user_logged_in.send(sender=user.__class__, user=user, request=request)
2 中间件request.user.is_authenticated为False问题修复
检查settings.py中MIDDLEWARE的顺序,确保django.contrib.auth.middleware.AuthenticationMiddleware放在你自定义的中间件之前,只有AuthenticationMiddleware执行完成后,request.user才会被赋值为当前登录的用户对象,否则会一直是匿名用户,is_authenticated固定返回False。正确的顺序示例如下:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', # 系统认证中间件必须在自定义中间件之前 'django.contrib.auth.middleware.AuthenticationMiddleware', # 你的自定义中间件放在此处 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
内容的提问来源于stack exchange,提问作者Dhruv Singhal
相关产品推荐
相关产品推荐

