使用Python Requests时请求发送至错误账户问题排查求助
多用户线程环境下API请求账户混淆问题排查
问题概述
部署在Heroku的Flask应用中,通过线程实现了用户可手动启停的持续数据拉取任务,每个用户拥有独立的access/refresh token。但偶尔出现账户混淆:用户A收到属于用户B的物品通知,切换为普通requests调用后问题仍存在。
核心原因分析
问题出在Handler类的类级共享字典allHeaders:
allHeaders是类属性,所有Handler实例共享同一个字典对象- 当多个用户的
Handler实例初始化时,self.requestHeaders = Handler.allHeaders.get("AllRequest")会让所有实例的requestHeaders指向同一个字典 - 后续修改
self.requestHeaders["x-acme-access-token"]和X-Acme-Date时,实际是在修改共享的类字典,导致线程间的token被互相覆盖 - 例如:用户A先初始化
Handler并设置自己的token,随后用户B初始化时修改了同一个共享字典的token,此时A的线程后续发起的请求会使用B的token,拉取到B的数据后错误推送给A
修复方案
修改Handler的初始化逻辑,为每个实例创建独立的请求头字典,避免共享状态:
class Handler: # 保持类级别的模板字典不变 allHeaders = { "TokenRequest": { "x-acme-identity-auth-domain": "api.acme.com", "User-Agent": "Acme Device Acme/0.0/iOS/15.2/iPhone", }, "AllRequest": { "Accept": "application/json", "x-acme-access-token": None, "X-Acme-Date": None, "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US", "Content-Type": "application/json", "User-Agent": "iOS/16.1 (iPhone Darwin) Model/iPhone Platform/iPhone14,2 AcmeOS/2.112.2", "Connection": "keep-alive", }, } def __init__(self, user: User) -> None: self.user = user # 创建模板字典的副本,每个实例拥有独立的headers self.requestHeaders = Handler.allHeaders.get("AllRequest").copy() self.refreshToken = user.acme_refresh_token self.accessToken = user.acme_access_token if self.refreshToken == "": self.registerAccount() self.requestHeaders["x-acme-access-token"] = self.accessToken self.requestHeaders["X-Acme-Date"] = self.getDate()
额外检查点
Handler.routes的线程安全性:如果routes是类属性且为只读,无需修改;若存在动态修改逻辑,同样需要确保每个实例拥有独立副本- 用户对象的线程安全:
user.running_status等状态字段在多线程读写时,需确保操作是原子性的(可使用threading.Lock保护) - 日志排查:在
start方法中添加日志,记录当前请求的用户ID、access token片段,便于后续验证修复效果
内容的提问来源于stack exchange,提问作者Alfred Kings
相关产品推荐
相关产品推荐

