🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
开篇:一个经典的口试题
“说说看,用户登录后拿到的 Token,前端应该怎么存?”
这个题目看似简单,却能清楚地分辨出一个前端开发者对安全的明白深度。是存到 localStorage?sessionStorage?照旧 Cookie?又大概是内存里?差别的选择背后,是截然差别的安全考量。
本日,来聊一聊 Token 的存储之道,让你不但知道怎么做,更明白为什么这么做。
选项一:Web Storage(localStorage / sessionStorage)
这是最直观、最轻易想到的方案。- // 登录成功后
- const token = 'your_jwt_token_here';
- localStorage.setItem('auth_token', token);
- // 后续请求时带上
- axios.interceptors.request.use((config) => {
- const token = localStorage.getItem('auth_token');
- if (token) {
- config.headers.Authorization = `Bearer ${token}`;
- }
- return config;
- });
复制代码 优点:
- 简单易用:API 简单,上手快。
- 永世存储(localStorage):除非手动打扫,否则不绝存在。
- 会话期存储(sessionStorage):页面关闭即打扫,更安全一点。
致命缺点:
- 极易受到 XSS (跨站脚本攻击) 的攻击。这是最核心的题目。如果网站存在 XSS 毛病,攻击者的恶意脚本可以轻易地读取到 localStorage 中的全部 Token,从而盗取用户身份。
结论: 不保举,尤其对于敏感应用。 除非你的应用完全不存在 XSS 风险(但这险些不大概),大概 Token 的安全级别要求不高。
选项二:Cookie
Cookie 是传统且常见的身份验证载体。- // 服务端设置 Cookie (HTTP Response Header)
- Set-Cookie: auth_token=your_jwt_token_here; Path=/; HttpOnly; Secure
- // 前端无需特殊处理,浏览器会自动在每次请求中携带
复制代码 注意这里的两个关键属性:
- HttpOnly:这是对抗 XSS 的神器。设置了 HttpOnly 的 Cookie 无法通过 JavaScript 的 document.cookie API 访问,这意味着纵然发生 XSS,攻击者也无法盗取到 Token。
- Secure:逼迫 Cookie 只能在 HTTPS 协议下被发送,防止在网络传输中被窃听。
优点:
- 免疫 XSS(得益于 HttpOnly):无法通过 JS 读取,安全性高。
- 可控制生命周期:通过 Expires 或 Max-Age 设置逾期时间。
- 自动管理:欣赏器自动在同源哀求中携带。
缺点:
- 轻易受到 CSRF (跨站哀求伪造) 的攻击。由于欣赏器会自动在哀求中带上 Cookie,攻击者可以诱导用户点击一个链接,从而以用户的身份发起恶意哀求。
- 须要额外的 CSRF 防护步伐,如使用 Anti-CSRF Token、验证 Origin/Referer Header 等。
结论: 是一个可行的方案,但必须配套美满的 CSRF 防御机制。
选项三:内存(Memory)
将 Token 生存在 JavaScript 变量中。- let inMemoryToken = null;
- // 登录成功后
- const login = async () => {
- const response = await loginAPI(username, password);
- inMemoryToken = response.data.token; // 存到内存变量
- };
- // 请求拦截器中添加
- axios.interceptors.request.use((config) => {
- if (inMemoryToken) {
- config.headers.Authorization = `Bearer ${inMemoryToken}`;
- }
- return config;
- });
- // 退出登录或页面刷新时,Token 消失
复制代码 优点:
- 安全性极高:由于 Token 只存在于当前页面的内存中,关闭页面或革新页面后 Token 立刻消散。XSS 攻击者很难通过一次性注入的脚本连续地盗取到 Token(除非攻击代码常驻内存)。
缺点:
- 体验差:页面一旦革新,Token 就没了,用户须要重新登录。这对于单页面应用 (SPA) 来说是致命的。
结论: 实用于安全要求极高、不介意频仍登录的场景(如银行体系)。 对于平常 Web 应用,体验不可继续。
终极方案:组合拳 + 架构头脑
既然没有美满的银弹,当代前端的最佳实践通常是 组合方案 和 架构优化。
实践一:Cookie(HttpOnly + Secure) + 防御 CSRF
这是最传统但依然非常妥当的方案。
- 后端在登录乐成后,设置一个 HttpOnly、Secure 的 Cookie 来存放 Token(可以是 JWT,也可以是 Session ID)。
- 前端根本不消费心 Token 的存储和携带题目,由欣赏器自动完成。
- 后端必须摆设美满的 CSRF 防护战略,比方:
- 从 Cookie 中读取 Token 或 Session ID 举行身份验证。
- 同时,要求哀求必须携带一个额外的(由后端天生并通过 API 返回给前端的)X-CSRF-Token Header,并与 Session 中存储的值举行比对。
实践二:Access Token + Refresh Token
这是如今 API 接口认证非常盛行的方案,美满办理了内存存储体验差的题目。
- 登录:用户输入暗码登录。
- 返回双 Token:服务端返回两个 Token:
- access_token:短期有用(比方 2 小时),用于哀求受掩护的 API。
- refresh_token:恒久有用(比方 7 天),仅用于获取新的 access_token,不应具备API访问权限。
- 存储战略:
- access_token:存入内存。如许纵然被 XSS 盗取,有用期也很短,风险可控。
- refresh_token:存入 HttpOnly Cookie。由于它有用期长,必须严加掩护。由于其自己不直接用于业务哀求,纵然遭遇 CSRF,攻击者也无法用它来做任何关键操纵(只能用来换一个短期的 access_token,而该 access_token 又会由于存在于内存而难以被攻击者获取)。
- 无感革新:当 access_token 逾期后,前端自动(通过 refresh_token)调用革新接口获取新的 access_token,用户无感知。
这个方案在安全性和用户体验之间取得了绝佳的平衡,是当前浩繁大型应用的首选。
总结与发起
给你的终极发起:
- 如果你在做的是一个简单的、内部使用的、对安全性要求不高的工具,用 localStorage 图个方便也无可厚非,但要清楚风险。
- 如果你在做的是一个传统的、服务端渲染的多页应用,使用 HttpOnly Cookie 并配套 CSRF 防护是尺度做法。
- 如果你在做的是一个当代化的 SPA(如 React/Vue 应用),剧烈保举研究并接纳 Access Token (内存) + Refresh Token (HttpOnly Cookie) 的方案。
安全没有绝对,只有相对的衡量。明白每种方案的利弊,并根据你的现实业务场景做出最得当的选择,才是最告急的。
如果对您有所资助,欢迎您点个关注,我会定时更新技能文档,各人一起讨论学习,一起进步。
免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金. |