当前位置: 首页 > article >正文

gunicorn多线程部署django导致的登陆错误

使用django写后端,认证系统使用了内存中的令牌存储(authentication.py中的user_tokens字典)。

from secrets import token_hex
from .models import User# Create a custom token generation function
def generate_token():return token_hex(20)  # Generate a 40-character hex token# Create an in-memory token storage (for demonstration)
# In production, you would use a database model for this
user_tokens = {}  # user_id: token# Custom authentication for DRF views
class CustomTokenAuthentication:def authenticate(self, request):auth_header = request.headers.get('Authorization')if not auth_header or not auth_header.startswith('Token '):return Nonetoken = auth_header.split(' ')[1]# Find user with this tokenfor user_id, user_token in user_tokens.items():if user_token == token:try:user = User.objects.get(id=user_id)return (user, token)except User.DoesNotExist:return Nonereturn Nonedef authenticate_header(self, request):return 'Token' 

当使用Gunicorn并配置多个工作进程时(workers = multiprocessing.cpu_count() * 2 + 1),每个工作进程都拥有独立的内存空间和自己的user_tokens字典副本。

这就导致:
用户登录时,其令牌仅存储在某个工作进程的内存中。
而后续请求可能会被路由到另一个没有该令牌内存记录的工作进程。
这将导致认证失败,从而触发前端api.js中的拦截器清除localStorage中的令牌。 

import axios from 'axios'// 创建一个axios实例
const apiClient = axios.create({baseURL: '/api',headers: {'Content-Type': 'application/json','Accept': 'application/json'},// 添加超时设置,避免请求挂起过长时间timeout: 10000
})// 请求拦截器 - 添加认证token
apiClient.interceptors.request.use(config => {// 每次请求时重新从localStorage获取token,确保使用最新tokenconst token = localStorage.getItem('upload_token')if (token) {config.headers.Authorization = `Token ${token}`}return config},error => {return Promise.reject(error)}
)// 响应拦截器 - 全局错误处理
apiClient.interceptors.response.use(response => {return response},error => {console.log('API请求错误:', error.response)// 处理401未授权错误if (error.response && error.response.status === 401) {// 可以在这里处理自动登出逻辑console.log('认证失败,清除令牌')localStorage.removeItem('upload_token')localStorage.removeItem('upload_user')window.location.href = '/login'}return Promise.reject(error)}
)// 简化的API请求方法
const optimizedApiClient = {get: (url, config = {}) => apiClient.get(url, config),post: (url, data, config = {}) => apiClient.post(url, data, config),put: (url, data, config = {}) => apiClient.put(url, data, config),delete: (url, config = {}) => apiClient.delete(url, config)
}export default optimizedApiClient 

导致用户登录-》进入其他页面-》重导到登录页反复横跳

处理:

临时处理:

        将gunicorn改成单线程

长期处理:

        建立token存储表单,采用持久化令牌存储方案:将令牌存入数据库表中,而非内存字典
确保所有工作进程都能访问同一份令牌数据

http://www.lryc.cn/news/2394833.html

相关文章:

  • (LeetCode 每日一题) 909. 蛇梯棋 (广度优先搜索bfs)
  • PostgreSQL ERROR: out of shared memory处理
  • 生成https 证书步骤
  • 34、请求处理-【源码分析】-Model、Map原理
  • 设计模式——适配器设计模式(结构型)
  • 小黑大语言模型通过设计demo进行应用探索:langchain中chain的简单理解demo
  • 秒杀系统—5.第二版升级优化的技术文档三
  • [SC]SystemC在CPU/GPU验证中的应用(六)
  • 【STM32】HAL库 之 CAN 开发指南
  • WPF的基础设施:XAML基础语法
  • DeepSeek R1-0528 新开源推理模型(免费且快速)
  • Go 语言的 GC 垃圾回收
  • [git每日一句]your branch is behind ‘origin/master‘
  • 【QT】在QT6中读取文件的方法
  • 安全帽目标检测
  • Java工厂方法模式详解
  • 【pytorch学习】土堆pytorch学习笔记2
  • Eclipse 插件开发 5.3 编辑器 监听输入
  • iOS 集成网易云信IM
  • Parasoft C++Test软件单元测试_实例讲解(对多次调用的函数打桩)
  • azure web app创建分步指南系列之二
  • 题海拾贝:P8598 [蓝桥杯 2013 省 AB] 错误票据
  • MySQL 8.0:解析
  • Python量化交易12——Tushare全面获取各种经济金融数据
  • 封装一个小程序选择器(可多选、单选、搜索)
  • Dest建筑能耗模拟仿真功能简介
  • 【Hot 100】121. 买卖股票的最佳时机
  • 【机器学习基础】机器学习入门核心算法:XGBoost 和 LightGBM
  • Linux | Shell脚本的常用命令
  • 跑步的强度等级分类