Express的CSRF令牌问题

时间:2014-08-03 05:03:18

标签: node.js angularjs express csrf

我正在尝试使用csurfexpress启用CSRF保护。我的应用程序使用Angular作为前端,所以我认为将其添加到我的应用程序就足够了:

app.use(cookieParser('test secret'));
app.use(cookieSession({
    secret: 'test secret'
}));
app.use(csrf({
    cookie: {
        key: 'XSRF-TOKEN'
    }
}));

然而,当我尝试发出POST请求时,我得到403("无效的CSRF令牌")错误。 据我所知,问题在于csrf-tokens模块:在第44行,expected变量看起来像qMnHLQGhivxECx5WtwuktDNA-snimacq30z-XNh2X-KTpdlkU6Og secrettoken变量看起来像qMnHLQGhivxECx5WtwuktDNA。由于expectedtoken不同,因此会发生403错误。

到目前为止,我已尝试过以下方法:

  • secure: false选项
  • 中设置signed: true和/或csurf
  • 确保我的cookie-sessioncookie-parser中间件在csurf之前运行
  • 重新安装我的所有npm模块以防万一
  • 在我的电脑上大喊

我可能会切换到基于会话的令牌,但这对Angular来说不会顺利运行,而且我不确定它是否能解决我的问题。

有谁知道如何解决这个问题,或者原因可能是什么?

PS 顺便说一下,我还注意到了一个(可能是无关的)问题:req.csrfToken()方法似乎返回的值与{{1}完全无关expected中的值或存储在cookie中的字符串。

1 个答案:

答案 0 :(得分:7)

有关csurf lib的错误/错误实现。饼干" XSRF-TOKEN"不存储csrf令牌,而是csurf用于生成csrf令牌的秘密。因此,应用程序的Angular部分标识XSRF-TOKEN并将标头正确附加到HTTP请求,但csurf中间件不会将该密钥识别为有效的CSRF标记本身。要解决此问题,您应该将其实现为:

var cookieParser = require('cookie-parser');
var cookieSession = require('cookie-session');
app.use(cookieParser("secret"));
app.use(cookieSession({secret: "secret2"}));
app.use(csrf());
app.use(function (req, res, next) {
    res.cookie("XSRF-TOKEN",req.csrfToken());
    return next();
});

req.csrfToken()将根据存储的秘密生成csrf令牌,在本例中,由csrf中间件生成的req.session.csrfSecret变量。然后,它会工作。

编辑:请参阅此问题on GitHub