Python requests更新Bearer Token后GET请求仍用旧凭证的问题
解决方法
1. 放弃用.env存储动态Token,改用内存缓存
动态生成的Bearer Token完全不需要写入.env文件——.env只适合存放静态凭证(比如获取Token用的client_id、client_secret),动态Token直接存在内存变量里是最可靠的方案。
修改逻辑:
- 程序启动时仅从.env加载静态密钥,只执行一次
- 维护全局/类级变量存储当前有效Token和过期时间
- 每次请求前检查Token是否即将过期,或收到401时重新获取Token并更新内存变量,直接用该变量发起请求
示例代码片段:
import os import time from dotenv import load_dotenv import requests # 加载静态凭证,仅初始化时执行 load_dotenv() CLIENT_ID = os.getenv("CLIENT_ID") CLIENT_SECRET = os.getenv("CLIENT_SECRET") # 内存存储Token及过期时间 current_token = None token_expires_at = 0 def fetch_new_token(): global current_token, token_expires_at # 调用Token获取接口 resp = requests.post("https://your-token-endpoint.com", data={ "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "grant_type": "client_credentials" }) resp.raise_for_status() token_data = resp.json() current_token = token_data["access_token"] # 留10分钟缓冲,避免Token刚到过期时间就失效 token_expires_at = time.time() + token_data["expires_in"] - 600 def make_api_call(): global current_token, token_expires_at # 主动检查Token有效性 if not current_token or time.time() >= token_expires_at: fetch_new_token() try: resp = requests.get("https://your-target-api.com", headers={ "Authorization": f"Bearer {current_token}" }) resp.raise_for_status() return resp.json() except requests.exceptions.HTTPError as e: if e.response.status_code == 401: # 强制刷新Token并重试一次 fetch_new_token() resp = requests.get("https://your-target-api.com", headers={ "Authorization": f"Bearer {current_token}" }) resp.raise_for_status() return resp.json() else: raise
2. 若必须用.env,更新后强制重新加载并刷新变量
如果因特殊需求必须将Token写入.env,每次更新后要执行两个关键操作:调用load_dotenv(override=True)强制覆盖环境变量,同时刷新存储Token的变量。
示例代码片段:
import os from dotenv import load_dotenv import requests def update_token_in_env(new_token): # 写入新Token到.env文件 with open(".env", "r") as f: lines = f.readlines() with open(".env", "w") as f: for line in lines: if line.startswith("BEARER_TOKEN="): f.write(f"BEARER_TOKEN={new_token}\n") else: f.write(line) # 强制重新加载.env,覆盖已有环境变量 load_dotenv(override=True) # 刷新Token变量 global bearer_token bearer_token = os.getenv("BEARER_TOKEN") def make_api_call(): global bearer_token try: resp = requests.get("https://your-target-api.com", headers={ "Authorization": f"Bearer {bearer_token}" }) resp.raise_for_status() return resp.json() except requests.exceptions.HTTPError as e: if e.response.status_code == 401: # 获取新Token并更新.env new_token = fetch_new_token() # 你的Token获取逻辑 update_token_in_env(new_token) # 重试请求 resp = requests.get("https://your-target-api.com", headers={ "Authorization": f"Bearer {bearer_token}" }) resp.raise_for_status() return resp.json() else: raise
3. Lambda环境的特殊处理
如果在AWS Lambda中运行,注意热启动会复用执行环境:
- 不要把Token存在模块级变量后就不再更新,每次函数执行前先检查Token有效性
- 静态凭证可以存在Lambda环境变量中,动态Token仍用内存缓存即可,无需落地
- 不要在Lambda中修改.env文件——执行环境是临时的,修改的文件无法在后续请求中稳定复用
核心注意事项
- 动态Token没必要落地到文件,内存缓存是最高效且无同步问题的方案
- 主动在Token过期前10分钟刷新,避免刚好在请求时触发401
- 401重试逻辑要限制次数,防止陷入无限循环
内容的提问来源于stack exchange,提问作者sashin samlal
相关产品推荐
相关产品推荐

