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

Django Rest Framework单用户多登录限制 JWT会话与配置报错问题

问题1:启动时报应用标签重复错误

原因

你在settings.py的INSTALLED_APPS中重复注册了users应用:users和users.apps.AccountsConfig都是指向同一个应用,导致Django识别到重复的应用标签。

解决方法

删除INSTALLED_APPS中的'users'行,仅保留'users.apps.AccountsConfig'即可,自定义的AccountsConfig可以正常生效,同时触发ready方法加载信号。
修改后的INSTALLED_APPS对应部分如下:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'rest_framework.authtoken',
    'corsheaders',
    'users.apps.AccountsConfig',
    # 其余后续应用
]

问题2:JWT登录时未生成会话记录

原因

确实是JWTAuthentication导致的。你参考的教程是基于Django默认的Session会话机制实现的:

  • Django默认的user_logged_in信号仅在调用auth.login()方法(也就是Session登录逻辑)时才会触发,而JWT登录接口的逻辑是校验用户名密码后直接返回token,不会调用auth.login(),也不会生成Django默认的session记录,因此信号不会触发,LoggedInUser表不会生成数据。
  • 你当前的信号逻辑也缺少对session_key字段的赋值,就算信号触发,该字段也会为空,无法用于后续的多端登录校验。

解决方法

根据你的技术选型有两种方案:

方案1:适配JWT机制修改逻辑

  • 在JWT登录接口校验用户身份成功后,手动创建/更新LoggedInUser记录,将JWT的唯一标识(比如jti)存入session_key字段
  • 自定义JWT校验逻辑,每次请求携带JWT时,先校验当前JWT的jti和数据库中该用户存储的jti是否一致,不一致则判定为无效登录,拒绝访问
  • 登出接口调用时手动删除LoggedInUser对应记录即可

方案2:改用SessionAuthentication

如果你的应用是前后端同域部署,可以将DRF的认证类改为SessionAuthentication,使用Django默认的Session登录逻辑,此时原有的信号逻辑可以正常触发,只需要补全信号中对session_key的赋值即可:

@receiver(user_logged_in)
def on_user_logged_in(sender, request, user, **kwargs):
    LoggedInUser.objects.update_or_create(
        user=user,
        defaults={"session_key": request.session.session_key}
    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:06:03