Ben*_*jen 21 ajax csrf connect node.js express
我正在尝试使用express.js框架在使用node.js构建的应用程序中实现CSRF保护.该应用程序充分利用了对服务器的Ajax post调用.我知道connect框架提供了CSRF中间件,但我不确定如何在客户端Ajax post请求的范围内实现它.
在stackoverflow中发布的其他问题中有关于此的一些部分,但我还没有找到一个相当完整的示例,说明如何从客户端和服务器端实现它.
有没有人有一个他们关心如何实现这个的工作示例?我看到的大多数示例都假设您在服务器端呈现表单,然后将其(以及嵌入式csrf_token表单字段)发送到客户端.在我的应用程序中,所有内容都通过Backbone.js在客户端(包括模板)上呈现.所有服务器都提供JSON格式的值,客户端的Backbone.js中的各种模型使用它们.根据我的理解,我需要先使用ajax检索csrf_token才能使用它.但是,我担心从安全角度来看这可能会有问题.这是一个有效的问题吗?
Fiz*_*han 32
可以通过meta为CSRF令牌添加标记然后在每个Ajax请求中传递CSRF令牌来完成
添加CSRF中间件
app.use(express.csrf());
app.use(function (req, res, next) {
res.locals.token = req.session._csrf;
next();
});
Run Code Online (Sandbox Code Playgroud)
您可以通过meta标签将CSRF令牌传递到客户端.对于前,在Jade
meta(name="csrf-token", content="#{token}")
Run Code Online (Sandbox Code Playgroud)
jQuery有一个名为ajaxPrefilter的功能,它允许您提供每个Ajax请求调用的回调.然后使用ajaxPrefilter设置标头.
var CSRF_HEADER = 'X-CSRF-Token';
var setCSRFToken = function (securityToken) {
jQuery.ajaxPrefilter(function (options, _, xhr) {
if (!xhr.crossDomain) {
xhr.setRequestHeader(CSRF_HEADER, securityToken);
}
});
};
setCSRFToken($('meta[name="csrf-token"]').attr('content'));
Run Code Online (Sandbox Code Playgroud)
server.js
...
// All Cookies/Sessions/BodyParser go first
app.use(express.csrf());
...
// Get the request
app.post('/ajax', function(req, res){
res.render('somelayout', {csrf_token: req.session._csrf});
});
Run Code Online (Sandbox Code Playgroud)
在somelayout.jade
input(type='hidden', name='_csrf', value=csrf_token)
Run Code Online (Sandbox Code Playgroud)
CSRF中间件仅在每个会话中生成一次csrf令牌,因此在用户访问期间可能不会更改.
此外,它不会检查GET和HEAD请求上的令牌.只要令牌在请求(标题,正文或查询)中,您就是好的.这就是它的全部内容.