Django默认登录系统异常:新登录用户覆盖其他用户请求身份
Django多用户登录会话覆盖问题排查与解决
问题核心:测试用例误用单一会话实例
Django的TestCase.client是全局单一会话对象,每次调用client.post登录新用户时,会直接覆盖之前的会话Cookie。你测试代码里的first_user = self.client.post(...)之后,self.client已经被第二个用户的会话接管,后续的first_user.client本质还是同一个self.client,所以所有请求都会使用最后一次登录的用户身份。
测试用例修复:为每个用户创建独立Client
要模拟多用户的独立会话,必须为每个用户单独初始化Client实例:
@patch('django.middleware.csrf.CsrfViewMiddleware.process_view') @patch('djoser.views.settings.PERMISSIONS.user_delete') def test_login_user_with_other_session_opened_with_3_users(self, mock_user_delete, mock_process_view): mock_process_view.return_value = None mock_user_delete.return_value = True logger.debug("user created") # 每个用户对应独立的Client实例,确保会话隔离 client1 = self.client_class() client2 = self.client_class() client3 = self.client_class() # 各自登录 client1.post(reverse('rest_framework:login'), data={"username": self.first_user.email, "password": "1am_th30nE"}) client2.post(reverse('rest_framework:login'), data={"username": self.second_user.email, "password": "1am_th30nE"}) client3.post(reverse('rest_framework:login'), data={"username": self.third_user.email, "password": "1am_th30nE"}) # 用各自的Client发起请求 response1 = client1.get(reverse('v1:auth-me')) response2 = client2.get(reverse('v1:auth-me')) response3 = client3.get(reverse('v1:auth-me')) self.assertEqual(response1.wsgi_request.user.email, self.first_user.email) self.assertEqual(response2.wsgi_request.user.email, self.second_user.email) self.assertEqual(response3.wsgi_request.user.email, self.third_user.email)
自定义LoginView的排查方向
你的CustomLoginView只是继承父类并调用构造方法,本身没有问题,但要排查项目中其他可能导致会话共享的点:
- 检查是否有自定义中间件错误地用类属性存储用户状态(类变量是所有实例共享的,会导致用户身份串线)
- 确认
SESSION_ENGINE配置正常(默认django.contrib.sessions.backends.db是安全的,不要用内存存储) - 排查是否有全局缓存逻辑错误缓存了用户身份信息
生产环境额外验证
如果测试修复后生产环境仍有问题,需要检查:
- 反向代理(如Nginx)是否配置了错误的会话粘滞或缓存策略,导致请求被强制路由到同一实例并共享会话
- 前端是否正确处理Cookie,没有在多用户场景下复用同一Cookie
内容的提问来源于stack exchange,提问作者dave
相关产品推荐
相关产品推荐

