Auth0请求时Access Token刷新频率及checkSession()使用疑问
问题分析与优化方案
你的思路完全没问题,每次请求都调用checkSession()确实冗余且影响性能,生产环境更合理的做法就是缓存Access Token,仅在令牌缺失、已过期或即将过期时再调用checkSession()刷新。
为什么多数示例会在请求前调用checkSession()?
这些示例大多是为了简化实现逻辑,帮新手快速完成“请求必带有效令牌”的基础需求,避开令牌存储、过期判断等细节。但这种做法在高频请求场景下会产生大量不必要的Auth0服务端请求,拖慢整体响应速度,并不适合生产环境。
优化后的实现思路
- 缓存令牌与过期时间:把获取到的Access Token和它的过期时间(可以用
auth.getAccessTokenExpiresIn()计算)存在本地(比如localStorage,或根据安全需求选择其他存储方式) - 请求前做令牌有效性校验:
- 如果没有缓存的令牌,或者令牌已过期/即将过期(建议提前1分钟刷新,避免请求过程中令牌失效),再调用
checkSession()获取新令牌 - 令牌有效则直接使用缓存值
- 如果没有缓存的令牌,或者令牌已过期/即将过期(建议提前1分钟刷新,避免请求过程中令牌失效),再调用
优化后的代码示例
const authLink = setContext(async () => { let token; const now = Date.now(); // 从本地缓存获取令牌和过期时间 const storedToken = localStorage.getItem('accessToken'); const tokenExpiry = localStorage.getItem('tokenExpiry'); // 校验令牌是否需要刷新 if (!storedToken || now > Number(tokenExpiry) - 60000) { try { await auth.checkSession(); token = auth.getAccessToken(); // 计算并存储新的过期时间 const expiresIn = auth.getAccessTokenExpiresIn() * 1000; localStorage.setItem('accessToken', token); localStorage.setItem('tokenExpiry', String(now + expiresIn)); } catch (e: any) { if (e.error !== "login_required" && e.error !== "consent_required") { console.log(e); } // 清空无效的缓存数据 localStorage.removeItem('accessToken'); localStorage.removeItem('tokenExpiry'); } } else { token = storedToken; } return { headers: { "Content-Type": "application/json", Authorization: token ? `Bearer ${token}` : "", }, }; });
注意事项
- 存储安全性:
localStorage存在XSS攻击风险,如果你的应用涉及敏感数据,可考虑使用HttpOnly Cookie配合Auth0的Cookie模式,或内存存储(但页面刷新后会丢失令牌,需要重新触发登录) - 过期容错:提前1分钟刷新令牌是为了避免令牌在请求发送到服务器的过程中过期,导致请求失败
- 异常处理:
checkSession()失败时(比如用户登录状态已失效),要清空本地缓存的无效令牌,避免后续请求使用过期值
内容的提问来源于stack exchange,提问作者Nicole Staline
相关产品推荐
相关产品推荐

