对Express上的某些请求禁用csrf验证

时间:2012-11-22 16:35:07

标签: node.js express csrf

我正在使用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路由。

4 个答案:

答案 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) => ...

这对我有用。