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

Service Worker架构:高效Token处理与网络请求同步方案咨询

在Service Worker中实现带自动更新的Auth Token管理机制

核心实现思路

不需要复杂的Proxy或Observables,通过维护一个当前有效的token获取Promise就能解决问题:所有网络请求都等待这个Promise完成以获取最新token;每次需要更新token时,重新发起token请求并替换这个Promise,新的请求会自动等待最新的Promise结果,天然实现请求排队等待逻辑。

完整代码实现

// Service Worker 全局变量
let currentTokenPromise;
const TOKEN_REFRESH_INTERVAL = 15 * 60 * 1000; // 15分钟

// 1. 封装获取/刷新token的函数
async function getOrRefreshToken() {
  // 如果已有正在进行的token请求,直接返回这个Promise,避免重复请求
  if (currentTokenPromise) {
    return currentTokenPromise;
  }

  try {
    // 发起token请求(替换成你的实际token接口)
    const response = await fetch('/api/auth/token', {
      method: 'POST',
      credentials: 'include' // 若需要携带cookie认证
    });
    const data = await response.json();
    const token = data.access_token;

    // 返回token,同时保存当前Promise
    currentTokenPromise = Promise.resolve(token);
    return token;
  } catch (error) {
    // 请求失败时重置Promise,避免后续请求一直等待失败的Promise
    currentTokenPromise = null;
    throw error;
  }
}

// 2. 初始化首次token获取
currentTokenPromise = getOrRefreshToken();

// 3. 设置定时刷新token
setInterval(async () => {
  // 重置当前Promise,触发新的token请求
  currentTokenPromise = null;
  await getOrRefreshToken();
}, TOKEN_REFRESH_INTERVAL);

// 4. 拦截网络请求并添加token
self.addEventListener('fetch', (event) => {
  // 只拦截需要授权的接口(根据你的实际需求调整)
  if (event.request.url.startsWith(self.location.origin + '/api/')) {
    event.respondWith(
      (async () => {
        try {
          // 等待当前token获取完成
          const token = await currentTokenPromise;

          // 克隆请求并添加Authorization头
          const authRequest = new Request(event.request, {
            headers: new Headers({
              ...event.request.headers,
              'Authorization': `Bearer ${token}`
            })
          });

          // 发送带授权的请求
          return fetch(authRequest);
        } catch (error) {
          // token获取失败时,可返回错误或重定向到登录(根据你的业务逻辑处理)
          return new Response('Authentication failed', { status: 401 });
        }
      })()
    );
  }
});

关键逻辑说明

  • 请求排队机制:当token正在获取(无论首次还是刷新),所有新发起的接口请求都会await currentTokenPromise,自动等待token请求完成后再继续,不会出现请求因token未就绪而失败的情况。
  • 避免重复请求:getOrRefreshToken函数会检查是否已有正在进行的token请求,确保同一时间只有一个token请求在发送,减少不必要的服务器压力。
  • 生命周期重置:每次定时刷新时,先将currentTokenPromise置为null,触发新的token请求,后续的请求会自动等待这个新的Promise,实现token生命周期的重置。
  • 错误处理:token请求失败时会重置Promise,避免后续请求一直绑定到失败的Promise上,同时在fetch拦截中可以根据业务需求处理认证失败的情况。

关于Proxy/Observables的补充

你提到的Proxy方案虽然能实现"可更新Promise",但对于Service Worker这种轻量环境来说,上述基于单一Promise的方案更简洁、易维护,不需要额外的抽象层。如果后续需要更复杂的状态监听(比如token过期前提前刷新、多状态通知),再考虑引入Observables会更合适,但当前需求用原生Promise完全足够。

内容的提问来源于stack exchange,提问作者UmbQbify

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:27:57