如何在Express SSR应用中实现CSRF Token?csurf包已废弃
在Express+SSR模板引擎中实现CSRF防护(替代废弃的csurf)
1. 安装依赖包
选用维护中的csrf包配合cookie-parser实现,执行以下命令安装:
npm install csrf cookie-parser express
2. 配置Express中间件
初始化Express并挂载必要中间件,生成CSRF密钥并存入Cookie,同时将令牌注入模板引擎:
const express = require('express'); const cookieParser = require('cookie-parser'); const { create, secretSync } = require('csrf'); const app = express(); const csrf = create({ cookie: true }); // 解析Cookie app.use(cookieParser()); // 生成/读取CSRF密钥,注入令牌到模板 app.use((req, res, next) => { if (!req.cookies.csrfSecret) { const secret = secretSync(); res.cookie('csrfSecret', secret, { httpOnly: true, // 禁止前端JS读取,防范XSS secure: process.env.NODE_ENV === 'production', // 生产环境强制HTTPS传输 sameSite: 'strict', // 限制跨站Cookie发送 maxAge: 24 * 60 * 60 * 1000 // 密钥有效期1天 }); req.csrfSecret = secret; } else { req.csrfSecret = req.cookies.csrfSecret; } // 将令牌注入模板变量(适配EJS/Pug/Handlebars等模板引擎) res.locals.csrfToken = csrf.create(req.csrfSecret); next(); }); // 解析表单提交的URL编码数据 app.use(express.urlencoded({ extended: true }));
3. 在SSR模板中嵌入令牌
以EJS为例,在表单中添加隐藏字段传入令牌:
<form method="POST" action="/submit-form"> <input type="hidden" name="_csrf" value="<%= csrfToken %>"> <!-- 其他表单字段 --> <button type="submit">提交</button> </form>
其他模板引擎可通过对应语法读取csrfToken变量,比如Pug用= csrfToken,Handlebars用{{csrfToken}}。
4. 验证CSRF令牌
在处理POST/PUT/DELETE等修改类请求的路由中,验证令牌有效性:
app.post('/submit-form', (req, res) => { // 从表单数据中获取令牌(AJAX请求可从X-CSRF-Token请求头读取) const token = req.body._csrf; try { csrf.verify(req.csrfSecret, token); // 验证通过,执行业务逻辑 res.send('表单提交成功'); } catch (err) { // 验证失败,返回403权限错误 res.status(403).send('CSRF验证失败'); } });
核心安全注意事项
- Cookie安全配置:
httpOnly、secure、sameSite三个参数必须严格设置,避免Cookie被窃取或跨站滥用。 - 令牌传递适配:AJAX请求可将令牌放在
X-CSRF-Token请求头中,后端对应从req.headers['x-csrf-token']读取验证。 - 生产环境规范:务必开启
secure: true,确保Cookie仅在HTTPS环境下传输;同时根据业务需求调整密钥有效期。
内容的提问来源于stack exchange,提问作者MandoMando
相关产品推荐
相关产品推荐

