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

如何使用Apollo实现React应用用户登录数据与状态持久化

Apollo客户端刷新保留用户登录状态的实现方案

方案1:使用Apollo缓存持久化(改造成本最低)

这个方案依赖Apollo生态的缓存持久化能力,直接将存在Apollo缓存中的响应式变量currentUserVar数据同步到LocalStorage,刷新后自动恢复缓存数据,不需要你手动维护用户信息的存储逻辑。
配置代码示例:

// index.tsx
import { InMemoryCache, ApolloClient, ApolloProvider } from '@apollo/client';
import { persistCache, LocalStorageWrapper } from 'apollo3-cache-persist';

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        currentUser: {
          read() { return currentUserVar(); }
        }
      }
    }
  }
});

// 应用初始化前先恢复缓存
persistCache({
  cache,
  storage: new LocalStorageWrapper(window.localStorage),
  // 配置白名单,只持久化用户相关缓存,避免冗余
  filter: (key) => key.includes('currentUser')
}).then(() => {
  const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache
  });
  // 挂载根组件
  ReactDOM.createRoot(document.getElementById('root')).render(
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  );
});

这个方案的优势是不需要修改服务端代码,除了用户状态之外,其他你存在Apollo缓存中的查询数据也可以按需持久化,减少重复请求。

方案2:初始化时主动拉取当前用户信息(安全性最高)

如果你的应用对数据准确性和安全性要求更高,推荐在应用启动时通过JWT主动向服务端拉取最新的用户信息,不需要在前端额外存储用户数据。
实现步骤:

  1. 服务端新增一个getCurrentUser查询接口,解析请求头中的JWT,返回对应用户的公开信息(id、邮箱等)
  2. 在应用根组件中增加初始化查询逻辑,代码示例:
// App.tsx
import { useQuery, gql } from '@apollo/client';

const GET_CURRENT_USER = gql`
  query GetCurrentUser {
    getCurrentUser {
      id
      email
    }
  }
`;

function App() {
  const { loading, data, error } = useQuery(GET_CURRENT_USER, {
    // 没有本地token时跳过请求
    skip: !localStorage.getItem('token'),
    onError: () => {
      // token无效时清空本地状态,跳转登录
      localStorage.removeItem('token');
      currentUserVar({ loggedIn: false });
    }
  });

  useEffect(() => {
    if (data?.getCurrentUser) {
      currentUserVar({
        ...data.getCurrentUser,
        loggedIn: true
      });
    }
  }, [data]);

  // 初始化加载中展示加载态
  if (loading && localStorage.getItem('token')) return <div>加载中...</div>;

  // 后续路由逻辑
  return <>{/* 应用路由 */}</>;
}

这个方案的优势是用户数据永远和服务端保持一致,避免本地存储被篡改导致的业务异常,不需要额外维护前端用户信息的存储逻辑。

补充注意事项

  • 无论选择哪种方案,都建议给JWT设置合理的过期时间,服务端每次请求都要校验JWT合法性,降低token被盗用的风险
  • 选择缓存持久化方案时,不要将密码、支付信息等敏感数据存入持久化缓存
  • 用户主动登出时,需要同时清空LocalStorage中的token、Apollo持久化缓存、currentUserVar的状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:45:04