前端架构师成长之路:避免将 JWT 存储在 localStorage 中
zhezhongyun 2025-01-12 20:16 45 浏览
看到很多文章介绍将 JWT 存储在 localStorage 中,事实上,个人觉得建议最好不要。这就是将敏感信息存储在 localStorage 中,对于安全问题来说是个挑战,对于客户端的行为在安全问题上多数是不可靠的。
先简单介绍一下本地存储。
本地存储
localStorage 是 HTML5 的一项新特征,它基本上允许 Web 开发人员使用 JavaScript 在用户的浏览器中存储想要的任何信息,十分简单。
在操作上,localStorage 只是一个可以添加或删除数据的 JavaScript 对象,下面是一段 localStorage 操作的示例代码,该代码片段将创建一个指定 Key 的localStorage 数据,并可以为其更新、删除数据。
export const useStorage = (
valKey = "authorization",
keyPrefix = "DevPoint"
) => {
const localKey = `${valKey}.${keyPrefix}`;
const save = (data) => {
window.localStorage.setItem(localKey, JSON.stringify(deepCopy(data)));
};
const get = () => {
const localData = window.localStorage.getItem(localKey);
if (localData && localData !== "") {
return JSON.parse(localData);
} else {
return false;
}
};
/**
* 清除 localStorage 中 valKey 的值
*/
const clear = () => {
window.localStorage.setItem(localKey, "");
};
return {
save,
get,
clear,
};
};
// 清除所有的 localStorage
export const cleanAll = () => {
window.localStorage.clear();
};
打开浏览器开发工具,在控制台窗口的 Application 的标签页下看到,左侧的 Storage 可以看到,如下图所示:
localStorage 是一个纯 JavaScript 对象。如果正在构建一个单页面站点,使用 localStorage 之类的东西意味着网页可以独立于任何 Web 服务器运行,只需要浏览器存储空间,而无需在服务器中存储任何数据。
此外,localStorage 的好处是大小限制:像 Cookie 一般是 4KB 的大小限制,而 localStorage 在所有主流浏览器中至少5MB 的数据存储。因此现在也越来越多的 Web 应用使用 localStorage 来存储一些数据。
安全问题
localStorage 尽管使用简单,但在安全问题上,没有任何的保护措施,这就意味着敏感信息存储在 localStorage 会带来安全问题。
将任何敏感信息存储在localStorage 中相当于在互联网中发布了这些信息。localStorage 设计的目的是为浏览器增加本地存储机制,被设计为简单的 key/avalue 存储,开发人员可以使用它来构建稍微复杂的单页应用程序。
当将敏感信息存储在 localStorage 中时,实际上是在使用世界上最危险的东西 JavaScript 将最敏感的信息存储在有史以来最糟糕的保险库中,绝对不是一个好注意
如果攻击者可以在您的网站上运行 JavaScript,他们就可以检索您存储在 localStorage 中的所有数据并将其发送到他们自己的域中。这意味着存储在 localStorage 中的敏感信息都有可能受到损害。
当然可能有足够的信息认为 Javascipt 无法在您的站点中运行,但是如果您的站点包含来自域外源的第三方 JavaScript 代码,例如一些第三方脚本库的CDN源:
- bootstrap 源
- jQuery
- 广告脚本
- 谷歌分析链接
- 跟踪脚本
- ...
一旦出现第三方脚本库被攻击了就会带来安全上的威胁,或许不曾使用第三方脚本库,又或者第三方脚本库绝对安全。
如果需要考虑所有可能的场景,为了降低安全事故的风险,建议尽量不要在 localStorage 中存储任何重要的敏感信息。
JWT 本质上与用户名/密码 在功能上相同,一旦知道 JWT 就相当于知道了用户名和密码。
如果攻击者可以获得 JWT 副本,就可以神不知鬼不觉的伪造请求向网站发出请求,因此建议不要将敏感信息存储在 localStorage 中。
JWT存储在 HttpOnly Cookie
本文只是介绍了将 JWT 存储在 localStorage 得不好,不推荐这样使用。
建议的方式是将JWT存储在 HttpOnly Cookie 中,优点是不需要在 JavaScript 代码中处理 Token , 后续请求中都会自动跟上 Token 信息的 Cookie。
再者 Cookie 的 HttpOnly 标签是防御 XSS 的解决方案之一,因为 HttpOnly 在简单的条件下阻止客户端(JavaScript)访问 Cookie。如果再将 secure 标志设置为 true,则只会在安全或加密的网络中使用 Cookie,从而增加其安全性。
虽然上面的方式可以防御 XSS ,但还存在另一个威胁即跨站请求伪造(CSRF),可以采用 CORS 白名单机制,并且 CSRF 令牌(可以参阅《CSRF 攻击:解析、预防和 CSRF 令牌》)与 JWT 一起使用。
但是在某些情况下,例如当 API 被移动应用程序使用并且它需要 Authorization Bearer xxx 标头而不是 Cookie 时,或者当需要使用同一个 JWT 向多个后端发出 HTTP 请求时,把 JWT 存在 localStorage 中的方案就更方便。
还有一点 Cookie 存储的大小为 4KB ,因此在使用这个方案的时候需要注意 JWT 的大小。如果 JWT 超过了 4KB 就不适合使用 Cookie 存储 JWT的方案。
总结
JWT 是一个非常流行的标准,可以使用签名来信任请求,并在各方之间安全的交换信息。在实际项目开发中,建议避免将 JWT 存储在 localStorage 中,而是存储在 HttpOnly Cookie 。
相关推荐
- perl基础——循环控制_principle循环
-
在编程中,我们往往需要进行不同情况的判断,选择,重复操作。这些时候我们需要对简单语句来添加循环控制变量或者命令。if/unless我们需要在满足特定条件下再执行的语句,可以通过if/unle...
- CHAPTER 2 The Antechamber of M de Treville 第二章 特雷维尔先生的前厅
-
CHAPTER1TheThreePresentsofD'ArtagnantheElderCHAPTER2TheAntechamber...
- CHAPTER 5 The King'S Musketeers and the Cardinal'S Guards 第五章 国王的火枪手和红衣主教的卫士
-
CHAPTER3TheAudienceCHAPTER5TheKing'SMusketeersandtheCardinal'SGuard...
- CHAPTER 3 The Audience 第三章 接见
-
CHAPTER3TheAudienceCHAPTER3TheAudience第三章接见M.DeTrévillewasatt...
- 别搞印象流!数据说明谁才是外线防守第一人!
-
来源:Reddit译者:@assholeeric编辑:伯伦WhoarethebestperimeterdefendersintheNBA?Here'sagraphofStea...
- V-Day commemorations prove anti-China claims hollow
-
People'sLiberationArmyhonorguardstakepartinthemilitaryparademarkingthe80thanniversary...
- EasyPoi使用_easypoi api
-
EasyPoi的主要特点:1.设计精巧,使用简单2.接口丰富,扩展简单3.默认值多,writelessdomore4.springmvc支持,web导出可以简单明了使用1.easypoi...
- 关于Oracle数据库12c 新特性总结_oracle数据库12514
-
概述今天主要简单介绍一下Oracle12c的一些新特性,仅供参考。参考:http://docs.oracle.com/database/121/NEWFT/chapter12102.htm#NEWFT...
- 【开发者成长】JAVA 线上故障排查完整套路!
-
线上故障主要会包括CPU、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如jstack、jmap等工具也是不囿于一个方面的问题...
- 使用 Python 向多个地址发送电子邮件
-
在本文中,我们将演示如何使用Python编程语言向使用不同电子邮件地址的不同收件人发送电子邮件。具体来说,我们将向许多不同的人发送电子邮件。使用Python向多个地址发送电子邮件Python...
- 提高工作效率的--Linux常用命令,能够决解95%以上的问题
-
点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf为什么要学习Linux命令?1、因为Li...
- linux常用系统命令_linux操作系统常用命令
-
系统信息arch显示机器的处理器架构dmidecode-q显示硬件系统部件-(SMBIOS/DMI)hdparm-i/dev/hda罗列一个磁盘的架构特性hdparm-tT/dev/s...
- 小白入门必知必会-PostgreSQL-15.2源码编译安装
-
一PostgreSQL编译安装1.1下载源码包在PostgreSQL官方主页https://www.postgresql.org/ftp/source/下载区选择所需格式的源码包下载。cd/we...
- Linux操作系统之常用命令_linux系统常用命令详解
-
Linux操作系统一、常用命令1.系统(1)系统信息arch显示机器的处理器架构uname-m显示机器的处理器架构uname-r显示正在使用的内核版本dmidecode-q显示硬件系...
- linux网络命名空间简介_linux 网络相关命令
-
此篇会以例子的方式介绍下linux网络命名空间。此例中会创建两个networknamespace:nsa、nsb,一个网桥bridge0,nsa、nsb中添加网络设备veth,网络设备间...
- 一周热门
- 最近发表
-
- perl基础——循环控制_principle循环
- CHAPTER 2 The Antechamber of M de Treville 第二章 特雷维尔先生的前厅
- CHAPTER 5 The King'S Musketeers and the Cardinal'S Guards 第五章 国王的火枪手和红衣主教的卫士
- CHAPTER 3 The Audience 第三章 接见
- 别搞印象流!数据说明谁才是外线防守第一人!
- V-Day commemorations prove anti-China claims hollow
- EasyPoi使用_easypoi api
- 关于Oracle数据库12c 新特性总结_oracle数据库12514
- 【开发者成长】JAVA 线上故障排查完整套路!
- 使用 Python 向多个地址发送电子邮件
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- HTML button formtarget 属性 (30)
- opacity 属性 (32)
- transition 属性 (33)