我正在尝试使用csurf
和express
启用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
secret
和token
变量看起来像qMnHLQGhivxECx5WtwuktDNA
。由于expected
和token
不同,因此会发生403错误。
secure: false
选项signed: true
和/或csurf
cookie-session
和cookie-parser
中间件在csurf
之前运行npm
模块以防万一我可能会切换到基于会话的令牌,但这对Angular来说不会顺利运行,而且我不确定它是否能解决我的问题。
有谁知道如何解决这个问题,或者原因可能是什么?
PS 顺便说一下,我还注意到了一个(可能是无关的)问题:req.csrfToken()
方法似乎返回的值与{{1}完全无关expected
中的值或存储在cookie中的字符串。
答案 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