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

Token认证:如何捕获401/403错误以实现令牌刷新?

捕获PouchDB 401/403错误并刷新令牌的方案

核心思路

PouchDB全局的.onError回调不会触发同步/复制流程中的401/403认证错误,需要从复制操作的事件监听和自定义HTTP请求拦截两个方向针对性处理。

方案一:在复制操作中捕获错误

你配置了live: true和retry: true,这类场景下的认证错误会触发复制对象的error事件,而非全局回调。可以按以下逻辑处理:

// 假设已有实现令牌刷新的函数
const refreshAuthToken = async () => {
  // 此处编写刷新令牌的业务逻辑,返回新的有效token
  const response = await fetch('/api/refresh-token');
  const data = await response.json();
  return data.token;
};

// 封装复制启动逻辑
const startReplication = async (authToken) => {
  const localDB = new PouchDB('local-db');
  const remoteDBInstance = remoteDB(authToken);

  const replication = localDB.sync(remoteDBInstance, {
    live: true,
    retry: true
  });

  // 监听复制错误事件
  replication.on('error', async (err) => {
    if (err.status === 401 || err.status === 403) {
      // 刷新令牌
      const newToken = await refreshAuthToken();
      // 终止当前复制进程
      replication.cancel();
      // 使用新令牌重新启动复制
      startReplication(newToken);
    } else {
      // 处理其他类型的复制错误
      console.error('复制异常:', err);
    }
  });
};

// 初始化启动复制
startReplication(initialAuthToken);

方案二:自定义HTTP适配器拦截请求

通过重写PouchDB的HTTP适配器,统一拦截所有请求的响应,自动处理令牌刷新和请求重试:

// 保存原始HTTP适配器
const originalHttpAdapter = PouchDB.adapters.http;

// 自定义适配器逻辑
PouchDB.adapter('custom-http', (opts, callback) => {
  const customOpts = {
    ...opts,
    // 重写ajax方法实现拦截
    ajax: function (ajaxOpts, ajaxCallback) {
      // 先执行原始请求
      originalHttpAdapter.ajax(ajaxOpts, async (err, res) => {
        if (err && (err.status === 401 || err.status === 403)) {
          try {
            // 刷新令牌
            const newToken = await refreshAuthToken();
            // 更新请求头的Authorization字段
            ajaxOpts.headers.Authorization = `Bearer ${newToken}`;
            // 使用新令牌重新发起请求
            originalHttpAdapter.ajax(ajaxOpts, ajaxCallback);
          } catch (refreshErr) {
            // 令牌刷新失败,返回错误
            ajaxCallback(refreshErr);
          }
        } else {
          // 无认证错误或其他错误,直接返回结果
          ajaxCallback(err, res);
        }
      });
    }
  };

  return originalHttpAdapter(customOpts, callback);
});

// 修改远程DB初始化逻辑,使用自定义适配器
const remoteDB = (authToken: string) => {
  return new PouchDB(remoteDBURL, {
    adapter: 'custom-http',
    headers: {
      Authorization: `Bearer ${authToken}`,
    }
  });
};

注意事项

  • 处理令牌刷新并发:如果多个请求同时触发401,需添加锁机制(比如用Promise缓存刷新请求),避免重复发起刷新令牌的请求。
  • 配合retry: true时,认证错误触发的自动重试无意义,必须先刷新令牌再重启复制或重新发起请求,否则会陷入无效重试循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 05:12:11