tyt*_*tho 13 csrf request node.js express angularjs
我在快递中实现了csrf(跨站点请求伪造)保护,如下所示:
...
app.use(express.csrf());
app.use(function (req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken());
next();
});
...
Run Code Online (Sandbox Code Playgroud)
这非常有效.Angularjs在通过$ http服务发出的所有请求中使用了csrf令牌.我通过我的角度应用程序发出的请求非常好.
我的问题是测试这些api端点.我正在使用mocha运行我的自动化测试和请求模块来测试我的api端点.当我使用请求模块向使用csrf(POST,PUT,DELETE等)的端点发出请求时,即使它正确使用了cookie等,它也会失败.
还有其他人提出解决方案吗?有人需要更多信息吗?
测试示例:
function testLogin(done) {
request({
method: 'POST',
url: baseUrl + '/api/login',
json: {
email: 'myemail@email.com',
password: 'mypassword'
}
}, function (err, res, body) {
// do stuff to validate returned data
// the server spits back a 'FORBIDDEN' string,
// which obviously will not pass my validation
// criteria
done();
});
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ohn 11
诀窍是你需要将你的POST测试包装在GET中并从cookie中解析必要的CSRF令牌.首先,假设您创建一个与Angular兼容的CSRF cookie,如下所示:
.use(express.csrf())
.use(function (req, res, next) {
res.cookie('XSRF-TOKEN', req.session._csrf);
res.locals.csrftoken = req.session._csrf;
next();
})
Run Code Online (Sandbox Code Playgroud)
然后,您的测试可能如下所示:
describe('Authenticated Jade tests', function () {
this.timeout(5000);
before(function (done) {
[Set up an authenticated user here]
});
var validPaths = ['/help', '/products'];
async.each(validPaths, function (path, callback) {
it('should confirm that ' + path + ' serves HTML and is only available when logged in', function (done) {
request.get('https://127.0.0.1:' + process.env.PORT + path, function (err, res, body) {
expect(res.statusCode).to.be(302);
expect(res.headers.location).to.be('/login');
expect(body).to.be('Moved Temporarily. Redirecting to /login');
var csrftoken = unescape(/XSRF-TOKEN=(.*?);/.exec(res.headers['set-cookie'])[1]);
var authAttributes = { _csrf: csrftoken, email: userAttributes.email, password: 'password' };
request.post('https://127.0.0.1:' + process.env.PORT + '/login', { body: authAttributes, json: true }, function (err, res) {
expect(res.statusCode).to.be(303);
request.get('https://127.0.0.1:' + process.env.PORT + path, function (err, res, body) {
expect(res.statusCode).to.be(200);
expect(body.toString().substr(-14)).to.be('</body></html>');
request.get('https://127.0.0.1:' + process.env.PORT + '/bye', function () {
done();
});
});
});
});
});
callback();
});
});
Run Code Online (Sandbox Code Playgroud)
我们的想法是实际登录并使用发布您从cookie中获取的CSRF令牌.请注意,您需要在mocha测试文件的顶部添加以下内容:
var request = require('request').defaults({jar: true, followRedirect: false});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6812 次 |
| 最近记录: |