如何使用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主动向服务端拉取最新的用户信息,不需要在前端额外存储用户数据。
实现步骤:
- 服务端新增一个
getCurrentUser查询接口,解析请求头中的JWT,返回对应用户的公开信息(id、邮箱等) - 在应用根组件中增加初始化查询逻辑,代码示例:
// 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
相关产品推荐
相关产品推荐

