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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 03:24:21