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

React Native封装Fetch统一校验JWT过期时间方案咨询

封装自定义Fetch实现全局Token过期校验方案

当然可以!封装一个全局的自定义Fetch工具完全能解决你重复写Token校验逻辑的问题,还能无缝集成Redux的Action分发。我给你一套落地可行的方案:

1. 先准备Token校验工具函数

首先我们需要两个核心函数:解析JWT获取过期时间,以及判断Token是否过期。可以借助jwt-decode库来简化解析(先执行npm install jwt-decode或yarn add jwt-decode安装)。

创建utils/api.js文件,先写基础工具函数:

import jwtDecode from 'jwt-decode';
import { store } from '../store'; // 导入你的Redux Store实例
import { logoutUser, refreshToken } from '../features/auth/authSlice'; // 导入你的Auth相关Action

// 解析JWT,提取过期时间等信息
const decodeJwtToken = (token) => {
  try {
    return jwtDecode(token);
  } catch (error) {
    console.error('解析JWT失败:', error);
    return null;
  }
};

// 判断Token是否已过期
const isTokenExpired = (token) => {
  if (!token) return true;
  const decodedToken = decodeJwtToken(token);
  if (!decodedToken?.exp) return true;
  
  // 把当前时间和Token过期时间转成秒级对比
  const currentTimestamp = Date.now() / 1000;
  return decodedToken.exp < currentTimestamp;
};

2. 封装带Token校验的自定义Fetch

接下来我们把Token校验、Redux Action分发和原生Fetch整合起来,实现全局的请求拦截逻辑:

export const customFetch = async (url, options = {}) => {
  // 从Redux Store中获取当前的Token和刷新Token
  const { auth } = store.getState();
  const { token, refreshToken: storedRefreshToken } = auth;

  // Step 1: 校验Token状态
  if (isTokenExpired(token)) {
    try {
      // 有刷新Token机制的话,先尝试刷新Token
      const refreshRes = await fetch('/api/auth/refresh', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ refreshToken: storedRefreshToken }),
      });

      if (refreshRes.ok) {
        const { newToken, newRefreshToken } = await refreshRes.json();
        // 分发Action更新Store里的Token
        store.dispatch(refreshToken({ token: newToken, refreshToken: newRefreshToken }));
        // 更新请求头的Authorization字段
        options.headers = {
          ...options.headers,
          Authorization: `Bearer ${newToken}`,
        };
      } else {
        // 刷新失败,直接分发登出Action
        store.dispatch(logoutUser());
        throw new Error('Token已过期且刷新失败');
      }
    } catch (refreshError) {
      console.error('刷新Token出错:', refreshError);
      store.dispatch(logoutUser());
      throw refreshError;
    }
  } else {
    // Token有效,自动添加Authorization请求头
    options.headers = {
      ...options.headers,
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    };
  }

  // Step 2: 发起实际的API请求
  try {
    const response = await fetch(url, options);
    // 额外处理401场景(比如Token被后台拉黑)
    if (response.status === 401) {
      store.dispatch(logoutUser());
      throw new Error('未授权访问');
    }
    return response;
  } catch (requestError) {
    console.error('API请求失败:', requestError);
    throw requestError;
  }
};

3. 在应用中使用自定义Fetch

现在你可以在任何需要请求API的地方,用customFetch替代原生的fetch,比如:

import { customFetch } from '../utils/api';

const fetchUserProfile = async () => {
  try {
    const res = await customFetch('/api/user/profile');
    const profileData = await res.json();
    // 处理用户数据
  } catch (err) {
    // 统一处理错误(比如提示用户登录)
  }
};

关键注意点

  • 确保你的Redux Store已经配置了redux-persist,Token会被自动持久化到本地存储(React Native中默认是AsyncStorage,不用额外处理)。
  • 如果你的项目没有刷新Token的机制,可以直接删掉刷新相关的代码,Token过期后直接分发登出Action即可。
  • 可以根据需求扩展这个自定义Fetch,比如添加全局的加载状态、统一的错误提示等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:20:29