You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 18:31:11