🤔Token 存储方案有哪些

🦉前言

作为 JavaScript + Express + Vue 开发者,本人之前都是使用LocalStorage进行Token的存储

今天来扩展下其他的存储方案,为后续的业务开发增加一些思路

一、为什么需要关注 token 存储?

在认证流程中,服务器颁发 token(如 JWT)后,客户端需要安全存储这些凭证。选择不当的存储方案可能导致:

  • 安全漏洞(如 XSS、CSRF 攻击)
  • 不良用户体验(如频繁重新登录)
  • 应用功能限制(如多标签页同步问题)

什么是XSS攻击?

全称:Cross-Site Scripting(跨站脚本攻击)

坏人把恶意代码(比如偷cookie的脚本)塞进网页,别人一打开网页就中招,相当于"网页里藏毒"。

一句话说就是坏人利用用户对网站的信任(恶意代码在网页里执行)。
什么是CSRF攻击?

Cross-Site Request Forgery(跨站请求伪造)(虽然XSS本该缩写是CSS,但为了和层叠样式表区分,改叫XSS)

坏人诱导你点链接/图,偷偷用你的登录状态发恶意请求(比如转账),相当于"冒充你的身份干坏事"。

一句话说就是坏人利用网站对用户浏览器的信任(伪造你的身份发请求)。

二、主要 token 存储方案及比较

1. LocalStorage

实现方式

javascript 复制代码
// 存储
localStorage.setItem('auth_token', token);

// 读取
const token = localStorage.getItem('auth_token');

// 删除
localStorage.removeItem('auth_token');

优势

  • 简单易用,API 直接
  • 持久化存储,浏览器关闭后仍然存在
  • 容量较大(通常 5MB+)

劣势

  • 易受 XSS 攻击:任何注入页面的恶意 JavaScript 都能读取
  • 无法自动随请求发送,需手动添加到请求头
  • 同源策略限制,子域名间不共享

适用场景:快速原型开发、对安全性要求不高的内部应用

2. SessionStorage

实现方式

javascript 复制代码
// 存储
sessionStorage.setItem('auth_token', token);

// 读取
const token = sessionStorage.getItem('auth_token');

// 删除
sessionStorage.removeItem('auth_token');

优势

  • 会话级存储,关闭标签页后自动清除
  • 同样简单易用的 API
  • 比 cookies 更大的存储空间

劣势

  • 同样易受 XSS 攻击(没错,又是它)
  • 多标签页间不共享(可能造成重复登录
  • 刷新页面会保留,但关闭标签页即清除

适用场景 :单标签页应用、高度敏感数据的临时存储

3. Cookies(HttpOnly + Secure)

补充

HttpOnly:阻止 JavaScript 访问 Cookie,有效防御 XSS 攻击窃取敏感信息。

Secure:仅允许通过 HTTPS 传输,防止中间人攻击(MITM)窃取 Cookie。
什么**中间人【Man-in-the-Middle Attack】*攻击? 简单说就是黑客在通信双方之间拦截或篡改数据,窃取敏感信息(如密码、Cookie)的攻击方式。此处不展开。

Express 服务器端设置

javascript 复制代码
res.cookie('auth_token', token, {
  httpOnly: true,
  secure: true, // 仅 HTTPS
  sameSite: 'strict', // 防止 CSRF
  maxAge: 24 * 60 * 60 * 1000 // 1天
});

优势

  • 防 XSShttpOnly 使 JavaScript 无法读取
  • 防 CSRF :配合 sameSite 属性
  • 自动随请求发送,无需手动处理
  • 可设置过期时间

劣势

  • 存储空间有限(约 4KB 每个 cookie,50 个左右/域名)
  • 需要服务器端配合设置
  • 每个请求都会携带,可能增加带宽消耗

适用场景:安全性要求高的生产环境,特别是 SSR 应用

4. Cookies(可被 JavaScript 读取)

Cookie简介: Cookie 是网站在用户浏览器中存储 的一小段数据(通常不超过 4KB ),用于跟踪用户会话、存储用户偏好或身份验证令牌 等。它由服务器通过 HTTP 响应头(Set-Cookie)发送给浏览器,之后浏览器会在每次请求中自动携带 Cookie(通过 Cookie 请求头)发送回服务器。

实现方式

javascript 复制代码
// 使用 js-cookie 库
Cookies.set('auth_token', token, { secure: true, sameSite: 'strict' });
const token = Cookies.get('auth_token');

优势

  • 比 localStorage 稍安全(可设置 secure 和 sameSite)
  • 自动过期管理
  • 可跨子域名共享(通过 domain 设置)

劣势

  • 仍然可能被 XSS 读取
  • 有存储空间限制

适用场景:需要子域名共享 token 且信任子域环境的场景

5. 内存存储

关键词:最安全的一种方式

为什么?

🍭因为 Token 只存在内存中,关闭页面就消失,完全不留痕迹,彻底杜绝持久化攻击风险。

Vue 实现

javascript 复制代码
// 在 Vuex/Pinia 中
const authStore = useAuthStore();
authStore.setToken(token);

// 或简单变量
let inMemoryToken = null;

优势

  • 最安全:完全不被持久化,关闭页面即消失
  • 不受存储限制
  • 无 XSS 持久化风险

劣势

  • 页面刷新即丢失,需重新认证
  • 多标签页间不共享
  • 需配合其他持久化方案使用

适用场景:极高安全要求的金融/医疗应用,通常配合短期 token 使用

6. IndexedDB

关键词:大容量!
IndexedDB 是浏览器提供的一种底层 NoSQL 数据库,允许网页应用大规模(通常 50MB+)存储结构化数据,支持异步高性能检索,适合离线 Web 应用存储复杂数据。

实现方式

javascript 复制代码
/* 前端代码中使用 */
// 使用 idb 库简化操作
const db = await openDB('authDB', 1, {
  upgrade(db) {
    db.createObjectStore('tokens');
  }
});

await db.put('tokens', token, 'auth_token');
const token = await db.get('tokens', 'auth_token');

优势

  • 大容量存储(通常 50MB+)
  • 异步操作,不阻塞 UI
  • 可加密存储(配合 Web Crypto API)

劣势

  • 仍然可能被 XSS 读取
  • API 较复杂
  • 老旧浏览器支持有限

适用场景 :需要存储大容量认证数据或加密需求的复杂应用

三、决策流程图

下方的流程图可以作为后续开发的一个方案选择思路

markdown 复制代码
是否需要自动随请求发送?
├─ 是 → 使用 Cookies
│   ├─ 需要防 XSS? → HttpOnly + Secure
│   └─ 需要 JS 读取? → 常规 Cookie + sameSite
└─ 否 → 
    ├─ 需要持久化?
    │   ├─ 是 → LocalStorage 或 IndexedDB
    │   └─ 否 → 内存存储
    └─ 需要最高安全性? → 内存存储 + 短期 token

✍️最后

技术的 不应该成为程序员的负担

技术多代表的,可供选择的一个个方案

而不是技术的枷锁

先写一个Demo

再去慢慢优化它吧

而不是被繁杂的技术吓住

很希望自己这句话能被年轻的我看到

不多说了

收摊!

相关推荐
南玖yy17 分钟前
深入理解 x86 汇编中的符号扩展指令:从 CBW 到 CDQ 的全解析
开发语言·汇编·arm开发·后端·架构·策略模式
行云流水62626 分钟前
js实现输入高亮@和#后面的内容
前端·javascript·css
涛哥码咖39 分钟前
前端十种排序算法解析
前端·算法·排序算法
村头的猫40 分钟前
建站SEO优化之站点地图sitemap
前端·经验分享·笔记
Sui_Network1 小时前
WAYE.ai 为Sui 上 AI 的下一个时代赋能
大数据·前端·人工智能·物联网·游戏
江梦寻1 小时前
软件工程教学评价
开发语言·后端·macos·架构·github·软件工程
掘金安东尼2 小时前
换了无数键盘、工学椅,却从没认真选过一块为程序员“注意力”设计的屏
前端·面试·github
戒不掉的伤怀2 小时前
react实现axios 的简单封装
javascript·react.js·ecmascript
美好的事情能不能发生在我身上2 小时前
苍穹外卖Day11代码解析以及深入思考
java·spring boot·后端·spring·架构
Bigger2 小时前
🍸 Apple Liquid Glass 设计理念与前端实现解析
前端·css·apple