我正在使用Express框架使用Node.js编写一个小型Web应用程序。我正在使用csrf中间件,但我想为某些请求禁用它。这是我在我的应用程序中包含它的方式:
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.cookieSession({secret: 'secret'}));
app.use(express.csrf());
我想在没有csrf控件的情况下设置POST路由。
答案 0 :(得分:29)
有几种可能的方法。您基本上需要了解决定是否使用csrf中间件的最简单和最正确的规则。如果你想要大多数时间使用csrf,除了请求模式的小白名单,请按照this answer I have about conditional logging middleware中的示例(为方便起见,在下面复制)。
var express = require("express");
var csrf = express.csrf();
var app = express.createServer();
var conditionalCSRF = function (req, res, next) {
//compute needCSRF here as appropriate based on req.path or whatever
if (needCSRF) {
csrf(req, res, next);
} else {
next();
}
}
app.use(conditionalCSRF);
app.listen(3456);
另一种方法可能只是在某个路径上使用中间件,例如app.post('/forms/*', express.csrf())
。您只是希望找到一种表达方式,以便在中间件将被使用或不被使用时使其保持清洁。
答案 1 :(得分:2)
由于Express中间件按顺序执行,因此您始终可以将语句置于代码中的csrf()语句之上。
像这样:
app.get '/ping', (req, res) -> res.status(200).end()
app.use csrf()
Express将在csrf令牌设置之前返回。对于非常少量的端点(我只有一个适合此类别的端点),我发现这是一个更清洁的解决方案。
此外,在撰写本文时,上述答案的代码如下所示:
customCsrf = (req, res, next) ->
if req?.url isnt '/ping'
return csrf()(req, res, next)
else
return next()
app.use customCsrf
额外的(req,res,next)绊倒了我一段时间,所以希望这对某人有所帮助。
答案 2 :(得分:1)
dailyjs.com有一篇关于csrf和express的好文章。它基本上是这样的:
使用csrf中间件:
app.configure(function() {
// ...
app.use(express.csrf());
// ..
});
创建一个自定义中间件,将局部变量token
设置为csrf值:
function csrf(req, res, next) {
res.locals.token = req.session._csrf;
next();
}
在您想要的每条路线中使用您的自定义中间件:
app.get('/', csrf, function(req, res) {
res.render('index');
});
在表单中创建一个包含csrf值的隐藏字段:
form(action='/contact', method='post')
input(type='hidden', name='_csrf', value=token)
答案 3 :(得分:1)
在快速应用级别使用中间件将每个 HTTP 方法添加到忽略列表中,以确保保护不默认验证。
例如
3.7
这会将 csrfToken() 方法注入每个请求对象,从而允许应用程序设置隐藏字段或可消费 cookie。
然后在您的中间件中将受保护的版本添加到所需的路由,并忽略不需要它的路由。
例如受保护
const ignoredMethods = [
'GET',
'HEAD',
'POST',
'PUT',
'DELETE',
'OPTIONS'
]
const csrfInit = csurf({ignoredMethods, cookie: true });
app.use(csrfInit);
例如未受保护
const csrfProtection = csurf({ cookie: true });
router.post('/api/foo', csrfProtection, (req, res, next) => ...
这对我有用。