React应用中Spotify Token基于剩余有效期的定时刷新实现
React中Spotify Token的智能刷新实现
问题场景
使用Spotify Token的React应用里,Token有效期为1小时。原先用useEffect+setInterval的方案,会在页面重启后不管旧Token是否有效,直接发起新请求,造成冗余调用。我们需要改成根据Token剩余有效期触发刷新,同时保持后续每小时自动刷新的逻辑。
已实现工具函数
先利用已有的剩余有效期计算函数,获取当前Token还剩多久过期:
export const calculateRemainingExpirationTime = expirationTime => { const currentTime = new Date().getTime(); const newExpirationTime = new Date(expirationTime).getTime(); const remainingTime = newExpirationTime - currentTime; return remainingTime; // 返回毫秒数 };
完整实现代码
下面是组件内的完整逻辑,包含页面刷新时的处理和后续自动刷新:
import { useEffect, useState } from 'react'; import { calculateRemainingExpirationTime } from './utils'; // 替换成你的文件路径 const SpotifyTokenManager = () => { // 从本地存储读取已有Token和过期时间(刷新页面不丢失) const [token, setToken] = useState(localStorage.getItem('spotifyToken')); const [expirationTime, setExpirationTime] = useState(localStorage.getItem('spotifyExpirationTime')); // 刷新Token的API调用逻辑 const refreshToken = async () => { try { // 替换成你的Spotify Token刷新接口 const res = await fetch('/api/refresh-spotify-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ refreshToken: localStorage.getItem('spotifyRefreshToken') }) }); const data = await res.json(); // 更新Token、过期时间到状态和本地存储 setToken(data.accessToken); setExpirationTime(data.expiresAt); // 假设接口返回ISO格式的过期时间字符串 localStorage.setItem('spotifyToken', data.accessToken); localStorage.setItem('spotifyExpirationTime', data.expiresAt); } catch (err) { console.error('Spotify Token刷新失败:', err); // 这里可以加失败后的降级处理,比如跳转登录页 } }; useEffect(() => { let timeoutId; let intervalId; const initTokenRefresh = () => { if (!expirationTime) { // 没有存储过期时间,直接刷新Token refreshToken(); return; } const remainingTime = calculateRemainingExpirationTime(expirationTime); if (remainingTime <= 0) { // Token已过期,立刻刷新 refreshToken(); } else { // 等剩余有效期结束后再刷新,刷新完设置每小时的定时任务 timeoutId = setTimeout(() => { refreshToken(); intervalId = setInterval(refreshToken, 3600 * 1000); // 1小时=3600秒,转毫秒 }, remainingTime); } }; // 页面加载时初始化刷新逻辑 initTokenRefresh(); // 组件卸载时清理定时器 return () => { timeoutId && clearTimeout(timeoutId); intervalId && clearInterval(intervalId); }; }, [expirationTime]); // 过期时间更新时,重新初始化刷新逻辑 return null; // 作为独立的管理组件,不需要渲染DOM }; export default SpotifyTokenManager;
核心逻辑说明
- 页面刷新时的处理:组件挂载后,先读取本地存储的过期时间。如果没有则直接刷新;有则计算剩余时间,已过期就立即刷新,未过期则等剩余时间到了再刷新。
- 后续自动刷新:第一次刷新Token后,启动每小时的定时任务,保证之后Token能持续自动更新。
- 状态持久化:把Token和过期时间存在
localStorage,避免页面刷新后丢失状态,确保每次加载都能基于之前的Token信息判断是否需要刷新。
内容的提问来源于stack exchange,提问作者gopinath krm
相关产品推荐
相关产品推荐

