返回博客列表
后端工程2026年8月20日2 分钟阅读
OAuth Token 生命周期:刷新、缓存与敏感信息保护
结合 Tesla Fleet API 接入,复盘 Partner Token、用户授权 Token、刷新轮换与失败重试的边界。
#Go#OAuth 2.0#可观测性

接入第三方 OAuth 时,最容易完成的是授权跳转,最容易留下问题的是授权之后:Token 放在哪里、何时刷新、并发刷新如何合并、401 是否重试、refresh token 轮换如何保存。
区分两类 Token
Partner Token 代表应用自身,用于注册合作方和服务间请求
Third-party Token 代表用户授权,只能访问用户允许的 scope
两者的 audience、scope、过期时间和存储策略不同
提前刷新而不是等到过期
缓存记录 expiresAt,并预留安全窗口。请求到来时,如果 Token 仍在有效窗口就直接使用;接近过期时只有一个协程执行刷新,其他请求等待同一结果,避免并发击穿授权服务器。
if token.ExpiresAt.Before(time.Now().Add(refreshWindow)) {
return refresher.Refresh(ctx)
}401 只重试一次
上游 401 可能表示 Token 被提前吊销。客户端清理缓存、刷新并重试一次;如果仍然失败,就把错误交给调用方。无限重试只会放大故障并隐藏配置问题。
Refresh Token 轮换
部分 OAuth 服务每次刷新都会返回新的 refresh token。保存新 Token 必须是原子操作,成功后旧 Token 立即失效。多实例环境需要共享存储和分布式互斥,同时对持久化内容加密。
浏览器会话
第三方 access token 不直接返回浏览器。浏览器只持有 HttpOnly、Secure、SameSite 合理配置的会话 Cookie,服务端根据会话读取加密后的 Token。
日志规则
Token 可以用于定位问题,但不应该成为日志内容。默认记录请求 ID、上游状态码、错误类型和刷新结果,不记录凭证本身。
明确当前限制
单实例原型使用内存会话是可以接受的,但必须在文档中写清楚:服务重启后需要重新授权,多实例前必须迁移到共享存储。