Web前端 认证token的安全存储策略

目录

方案概述

核心思路:

架构设计:

三层存储策略:

风险接受说明:

接受的风险:

防御的风险:

一句话部署:

[🛡️ Next.js XSS 防御终极方案](#🛡️ Next.js XSS 防御终极方案)

一、必须做的3件事(核心防御)

[1. 永远不用或净化 dangerouslySetInnerHTML](#1. 永远不用或净化 dangerouslySetInnerHTML)

[2. API Routes 必须验证输入](#2. API Routes 必须验证输入)

[3. 配置CSP安全头](#3. 配置CSP安全头)

二、4个绝对禁止

[❌ 永远不要用这些:](#❌ 永远不要用这些:)

三、3个必须验证

用户控制的跳转/加载必须验证:

四、开发习惯2条

[1. 数据只通过React传递](#1. 数据只通过React传递)

[2. 第三方库配置安全选项](#2. 第三方库配置安全选项)

五、检查清单(部署前)

一句话总结:


前言:最安全的方案不一定用户体验最优,需根据合适的场景选择安全策略。

**这里,我主要针对大多数常规业务场景下的实施方案进行分析。**这些方案通常不适用于银行、金融、支付等高安全性场景,因为这类场景通常需要进行二次生物验证或其他安全性较强但可能影响用户体验的验证措施。

方案概述

核心思路:

用短期内存token保证安全,用长期refresh_token保证体验,用XSS防御保证token不通过代码窃取。

架构设计:

三层存储策略:

🔐 第一层:access_token → sessionStorage(15分钟)

  • 页面关闭自动清除

  • XSS难窃取(短暂窗口)

🔐 第二层:refresh_token → localStorage(30天)

  • 接受扩展窃取风险

  • 用户可手动清除

🔐 第三层:关键操作 → 二次验证

  • 支付、改密等需要额外验证

双重刷新机制:

🔄 主动刷新:每14分钟自动刷新access_token
🔄 被动刷新:401时自动用refresh_token换新token
🔄 无缝体验:用户无感知,保持30天免登录

XSS全面防御:

✅ Next.js自动转义所有JSX
✅ CSP阻止外部脚本加载
✅ 禁止dangerouslySetInnerHTML(或必须净化)
✅ API层输入验证
✅ 绝不使用eval/innerHTML

风险接受说明:

接受的风险:

  1. 浏览器扩展可能读取localStorage(用户已同意安装)

  2. 用户电脑木马可能窃取token(超出Web防护范围)

  3. 物理接触电脑可能获取token(用户责任)

防御的风险:

  1. 网站XSS攻击(通过严格CSP和Next.js防护)

  2. CSRF攻击(SameSite Cookie + 后端验证)

  3. Token长期泄露(access_token仅15分钟有效)

  4. 重放攻击(JWT jti + 短期有效期)

一句话部署:

sessionStorage存15分钟access_token,localStorage存30天refresh_token,配置严格CSP,定期npm audit。

🛡️ Next.js XSS 防御终极方案

一、必须做的3件事(核心防御)

1. 永远不用或净化 dangerouslySetInnerHTML

2. API Routes 必须验证输入

javascript 复制代码
// pages/api/xxx.js 或 app/api/xxx/route.js
export default function handler(req, res) {
  const { content } = req.body;
  
  // 必须验证
  if (!content || typeof content !== 'string') {
    return res.status(400).json({ error: 'Invalid input' });
  }
  
  // 存储前转义
  const safeContent = escapeHtml(content);
  // ...保存到数据库
}

3. 配置CSP安全头

javascript 复制代码
// next.config.js(一次性配置)
module.exports = {
  async headers() {
    return [{
      source: '/(.*)',
      headers: [
        {
          key: 'Content-Security-Policy',
          value: "default-src 'self'; script-src 'self';"
        }
      ]
    }];
  }
};

二、4个绝对禁止

❌ 永远不要用这些:

javascript 复制代码
1. element.innerHTML = ...
2. document.write(...)
3. eval(userCode)
4. new Function(userCode)

三、3个必须验证

用户控制的跳转/加载必须验证:

javascript 复制代码
// 1. URL跳转
if (url.startsWith('/') || url.startsWith('https://yourdomain.com')) {
  window.location.href = url;
}

// 2. iframe/src属性
const allowedDomains = ['https://youtube.com'];
const isSafe = allowedDomains.some(d => url.startsWith(d));

// 3. 动态脚本
// 不要创建和执行用户提供的脚本

四、开发习惯2条

1. 数据只通过React传递

javascript 复制代码
// ✅ 好习惯
const [data, setData] = useState('');
useEffect(() => {
  const raw = localStorage.getItem('data');
  setData(raw); // React自动转义
}, []);

// ❌ 坏习惯
useEffect(() => {
  const raw = localStorage.getItem('data');
  document.getElementById('output').innerHTML = raw; // 绕过React
}, []);

2. 第三方库配置安全选项

javascript 复制代码
// 如markdown解析器
new MarkdownIt({
  html: false, // 禁止HTML标签
  xhtmlOut: true
});

五、检查清单(部署前)

✅ CSP安全头已配置

✅ 没有使用未净化的 dangerouslySetInnerHTML

✅ API Routes 都有输入验证

✅ 没有使用 innerHTML/document.write/eval

✅ 用户跳转链接都验证了域名

✅ 运行 npm audit 无高危漏洞

✅ 所有依赖都是最新版本

✅ HTTPS已启用

一句话总结:

在Next.js中,只要:

  1. 不用(或净化)dangerouslySetInnerHTML

  2. API Routes验证所有输入

  3. 配置CSP安全头

  4. 绝不使用 innerHTML/eval

其他时候React自动保护你,XSS风险极低。

总之,在配置和代码中进行预防,安全意识少不了。

相关推荐
cpolar技术支持1 小时前
本地 Playwright 测试报告怎么远程复盘?Trace Viewer 跑起来后,用 cpolar 分享失败现场
前端·自动化测试·测试工具·cpolar·playwright
wordbaby1 小时前
企业级后台管理系统路由设计与最佳实践指南
前端
胡志辉的博客1 小时前
【完全开源】IP 纯净度检测 可一键部署到自己的CF
前端·javascript·chrome·ip·chromium
Hilaku2 小时前
作为面试官,我最怕遇到什么样的候选人?
前端·javascript·程序员
TiDi2 小时前
Pinia优化重复请求
前端
web3d5202 小时前
01-用 Leafletjs 10 分钟搭一张水利一张图(Vue3 + Vite 实战)
前端·javascript
晚安日记wanna2 小时前
Vue2 的 defineProperty 差在哪四层追问筛掉九成候选人
前端·vue.js·面试
TiDi2 小时前
吸顶导航交互实现
前端
kisshyshy2 小时前
从Props透传到自定义Hook:系统梳理React跨层级通信与逻辑复用
前端·架构·代码规范
yume_sibai2 小时前
05-Flutter实战项目
前端·flutter