脚本能自动刷新Access Token吗?

wen 实用脚本 2

本文目录导读:

脚本能自动刷新Access Token吗?

  1. 方式一:使用 Refresh Token(最推荐、最安全)
  2. 方式二:自动重试+再次获取(适用于无法获取 Refresh Token 的场景)
  3. 方式三:利用第三方库自动管理(最省力)
  4. 注意事项:

脚本完全可以自动刷新 Access Token,这是几乎所有现代 API 客户端(如百度网盘、飞书、微信、OpenAI、GitHub)的标准做法。

常见的实现方式有两种,具体取决于你使用的 Token 类型和认证流程:

使用 Refresh Token(最推荐、最安全)

这是 OAuth 2.0 标准流程,服务器在返回 access_token 时,会同时返回一个 refresh_token(通常有效期为几天或几个月)。

流程图解:

初始请求:  app.get('/data')
2. 返回 401:  "Token expired"
3. 脚本自动:  用 refresh_token 请求 /token/refresh
4. 服务器返回: 新的 access_token + 新的 refresh_token(可选)
5. 脚本重试:  用新 access_token 请求 /data
6. 返回成功

Python 示例代码(使用 requests 库):

import requests
import time
class TokenManager:
    def __init__(self, client_id, client_secret, refresh_token):
        self.client_id = client_id
        self.client_secret = client_secret
        self.refresh_token = refresh_token
        self.access_token = None
        self.expires_at = 0  # 过期时间戳
    def get_token(self):
        """获取或刷新 Access Token"""
        if self.access_token is None or time.time() >= self.expires_at:
            self._refresh()
        return self.access_token
    def _refresh(self):
        """实际刷新 Token"""
        url = "https://api.example.com/oauth/token"
        data = {
            "grant_type": "refresh_token",
            "refresh_token": self.refresh_token,
            "client_id": self.client_id,
            "client_secret": self.client_secret
        }
        resp = requests.post(url, data=data)
        resp.raise_for_status()
        result = resp.json()
        self.access_token = result["access_token"]
        # 服务器通常返回 expires_in(秒数),计算过期时间
        self.expires_at = time.time() + result.get("expires_in", 3600) - 60  # 提前60秒刷新
        # 有些服务器会更新 refresh_token,建议也保存
        if "refresh_token" in result:
            self.refresh_token = result["refresh_token"]
    def api_request(self, url, **kwargs):
        """带自动刷新的API请求"""
        headers = kwargs.get("headers", {})
        headers["Authorization"] = f"Bearer {self.get_token()}"
        kwargs["headers"] = headers
        resp = requests.get(url, **kwargs)
        # 如果返回401(未授权),可能是Token过期,强制刷新重试
        if resp.status_code == 401:
            print("Token expired, refreshing...")
            self._refresh()
            headers["Authorization"] = f"Bearer {self.access_token}"
            resp = requests.get(url, **kwargs)
        return resp
# 使用示例
manager = TokenManager("your_client_id", "your_client_secret", "your_refresh_token")
response = manager.api_request("https://api.example.com/user/info")
print(response.json())

自动重试+再次获取(适用于无法获取 Refresh Token 的场景)

有些 API(如某些简单的私人接口)只给一个短期 Token,没有 Refresh Token,这时脚本需要检测到 Token 过期 → 重新用账号密码或API Key获取新 Token → 重试请求

实现思路:

def authed_request(url, get_new_token_func):
    """带自动重试的请求包装器"""
    token = get_new_token_func()  # 先获取一次
    headers = {"Authorization": f"Bearer {token}"}
    resp = requests.get(url, headers=headers)
    if resp.status_code == 401:
        # Token 过期,重新获取
        print("Token expired, fetching new one...")
        token = get_new_token_func()  # 这里调用你的登录/申请新Token的函数
        headers["Authorization"] = f"Bearer {token}"
        resp = requests.get(url, headers=headers)
    return resp

利用第三方库自动管理(最省力)

很多语言的 HTTP 客户端库内置了 Token 管理功能:

  • Python: requests-oauthlibauthlibgoogle-auth
  • Node.js: axios-oauth-clientsimple-oauth2
  • JavaScript (浏览器): @azure/msal-browser(微软认证)、keycloak-js

示例:使用 authlib 库(更简洁)

from authlib.integrations.requests_client import OAuth2Session
session = OAuth2Session(
    client_id="xxx",
    client_secret="xxx",
    token_endpoint="https://api.example.com/oauth/token",
    refresh_token_url="https://api.example.com/oauth/token",
    grant_type="refresh_token",
)
# 第一次需要手动设置 refresh_token
session.token = {"refresh_token": "your_initial_refresh_token"}
# 之后的请求会自动刷新
resp = session.get("https://api.example.com/user/info")
# 如果返回401,session会自动调用 refresh_token 并重试

注意事项:

  1. Refresh Token 也可能过期:部分服务器(如微信、支付宝)的 Refresh Token 有效期有限(通常几个月),过期后需要用户重新授权。
  2. 并发问题:如果多个线程/协程同时使用同一个 Token,需要加锁防止重复刷新。
  3. 安全性
    • 不要把 Refresh Token 硬编码在脚本里,应使用环境变量或密钥管理服务。
    • 如果脚本在用户设备上运行(如桌面应用),使用 PKCE 流程替代 client_secret
  4. 速率限制:频繁刷新 Token 可能被服务器限流,建议在代码里至少缓存到过期时间的前几分钟才刷新。
  • 如果有 Refresh Token:写一个 TokenManager 类,在每次请求前检查过期时间,自动刷新,这是推荐方案
  • 如果没有 Refresh Token:捕获 401 错误,自动重新登录获取新 Token 并重试。
  • 如果需要生产级稳定性:用 authlibrequests-oauthlib 等成熟库。

需要我帮你写一个针对某个具体平台(如百度网盘、飞书、微信、OpenAI等)的自动刷新脚本吗?

抱歉,评论功能暂时关闭!