共计 1925 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点:AJAX 请求中的 Token 风险
在前后端分离架构中,Token 是身份验证的核心载体,但常见安全隐患包括:

- CSRF(跨站请求伪造):攻击者诱导用户发送伪造请求,利用已登录状态执行恶意操作。
- XSS(跨站脚本攻击)窃取 Token:通过注入恶意脚本窃取本地存储的 Token。
- 权限越权:Token 权限设计不当导致用户访问未授权资源。
技术对比:三种 Token 存储方案
| 方案 | 安全性 | 性能 | 适用场景 |
|---|---|---|---|
| Cookie Token | 较高(HttpOnly 防护 XSS) | 自动携带 | 需防御 CSRF 的传统应用 |
| LocalStorage | 较低(易受 XSS 攻击) | 手动管理 | 纯 API 驱动的 SPA 应用 |
| JWT | 中高(依赖签名算法) | 无状态 | 分布式微服务架构 |
核心实现:Node.js 双重 Token 方案
1. 依赖安装
npm install express jsonwebtoken csrf cookie-parser
2. CSRF Token 生成中间件
// middleware/csrf.js
const csrf = require('csrf');
const tokens = new csrf();
exports.generateCSRFToken = (req, res, next) => {req.csrfToken = tokens.create(process.env.CSRF_SECRET);
res.cookie('XSRF-TOKEN', req.csrfToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production'
});
next();};
3. JWT 生成与验证
// utils/jwt.js
const jwt = require('jsonwebtoken');
// HS256 比 RS256 更适合中小型应用性能需求
const generateToken = (userId) => {
return jwt.sign({ sub: userId},
process.env.JWT_SECRET,
{expiresIn: '1h'}
);
};
const verifyToken = async (token) => {
try {return await jwt.verify(token, process.env.JWT_SECRET);
} catch (err) {throw new Error('Invalid token');
}
};
4. Axios 拦截器配置
// frontend/src/api.js
import axios from 'axios';
const instance = axios.create({baseURL: process.env.API_BASE_URL});
instance.interceptors.request.use(config => {const token = localStorage.getItem('jwt');
if (token) {config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
安全增强措施
1. Cookie 安全配置三要素
res.cookie('token', value, {
httpOnly: true, // 阻止 JavaScript 访问
secure: true, // 仅 HTTPS 传输
sameSite: 'strict' // 禁止跨站发送
});
2. JWT 黑名单实现
// service/tokenBlacklist.js
const blacklist = new Set();
const addToBlacklist = (token) => {blacklist.add(token);
setTimeout(() => blacklist.delete(token), 3600000); // 1 小时后自动清除
};
const isBlacklisted = (token) => blacklist.has(token);
生产环境避坑指南
- 未设置 Token 过期时间
- 坏实践:
jwt.sign(payload, secret) -
修复:始终添加
expiresIn参数 -
敏感数据存储在 JWT
- 坏实践:在 payload 包含用户密码
-
修复:仅存储用户 ID 等必要标识
-
CSRF Token 未绑定用户会话
- 坏实践:所有用户使用相同 CSRF 密钥
- 修复:将 CSRF Token 与用户 ID 关联
延伸思考
在实际项目中,如何平衡 Token 有效期与用户体验?缩短有效期增强安全性但会导致频繁重新登录,延长有效期则增加风险。可能的解决方案:
– 主 Token(1 小时过期)+ Refresh Token(7 天过期)
– 基于用户行为动态调整有效期(如活跃会话延长)
– 关键操作需二次认证
安全永远是权衡的艺术,需要根据具体业务场景选择最适合的方案。
正文完
发表至: 未分类
近两天内
