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
相关产品推荐
相关产品推荐

