GraphQL/Apollo安全存储JWT凭证:替代LocalStorage的方案及行业标准
GraphQL/Apollo 中JWT令牌的安全存储方案
一、LocalStorage 存JWT的核心风险
LocalStorage里的内容能被页面内的JavaScript直接读取,一旦页面存在XSS漏洞,攻击者注入的恶意脚本就能轻松窃取令牌,进而冒充用户操作——这是它最致命的安全问题。
二、安全替代方案
1. HttpOnly + Secure Cookie(首推)
完全可以把JWT存在Cookie里,这还是当前行业主流的安全方案:
- 关键配置项:
HttpOnly:禁止前端JavaScript访问Cookie,从根源上避免XSS窃取令牌Secure:仅在HTTPS连接下传输Cookie,防止令牌在网络中明文泄露SameSite:设为Strict或Lax,前者严格禁止跨站请求携带Cookie,后者允许部分安全的跨站场景(比如用户主动点击链接),有效防范CSRF攻击Path:限制Cookie生效路径(比如/graphql),缩小令牌的暴露范围
- Apollo适配方式:浏览器会自动在请求时携带符合条件的Cookie,不需要前端手动读取令牌。如果是跨域场景,只需在
createHttpLink里配置credentials: 'include',示例代码:
import { createHttpLink } from '@apollo/client'; import { ApolloClient, InMemoryCache } from '@apollo/client'; const httpLink = createHttpLink({ uri: '/graphql', // 跨域请求时携带Cookie,同域可用'same-origin' credentials: 'include', }); const client = new ApolloClient({ link: httpLink, cache: new InMemoryCache() });
2. 短有效期访问令牌 + 刷新令牌(结合Cookie)
进一步提升安全性的方案:
- 把**访问令牌(Access Token)**设为短有效期(比如15分钟),存在HttpOnly Cookie中;**刷新令牌(Refresh Token)**设为较长有效期(比如7天),同样存在HttpOnly Cookie中
- 当访问令牌过期,前端调用刷新接口,用刷新令牌获取新的访问令牌,全程不需要前端手动存储或操作令牌,由浏览器自动管理
- Apollo适配示例(处理令牌过期逻辑):
import { createHttpLink, from } from '@apollo/client'; import { onError } from '@apollo/client/link/error'; import { ApolloClient, InMemoryCache } from '@apollo/client'; const httpLink = createHttpLink({ uri: '/graphql', credentials: 'include', }); // 捕获认证错误,自动刷新令牌 const errorLink = onError(({ graphQLErrors, operation, forward }) => { const isUnauthenticated = graphQLErrors?.some(err => err.extensions?.code === 'UNAUTHENTICATED'); if (isUnauthenticated) { // 调用GraphQL的刷新令牌mutation return fetch('/graphql', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: 'mutation RefreshToken { refreshToken { accessToken } }' }) }) .then(res => res.json()) .then(() => forward(operation)) // 刷新成功后重发原请求 .catch(() => window.location.href = '/login'); // 刷新失败跳转登录 } }); const client = new ApolloClient({ link: from([errorLink, httpLink]), cache: new InMemoryCache() });
3. 内存存储(会话级)
把令牌存在前端内存里,比如React组件的state、全局状态管理工具(Redux、Zustand等):
- 优点:页面刷新后令牌自动消失,就算发生XSS攻击,也无法持久窃取令牌(只能在当前会话期间临时盗用)
- 缺点:用户刷新页面后需要重新登录,体验会打折扣,适合对安全性要求极高、可接受稍差体验的场景
三、Cookie存储是否为行业标准?
是的,配置了HttpOnly+Secure+SameSite的Cookie存储方案,是当前Web应用处理认证令牌的行业标准之一。相比LocalStorage,它能同时防范XSS和CSRF攻击,安全性更有保障,绝大多数大型Web应用(电商、社交平台等)都在使用这种方案。
内容的提问来源于stack exchange,提问作者fxxx
相关产品推荐
相关产品推荐

