我正在使用 supertest
测试我的API我想检查我的CSRF令牌保护是否有效,然后为其他测试禁用它。
为此,我将NODE_ENV
设置为test
或not_test
app.js
var csrf = require('csurf');
var app = express();
if (process.env.NODE_ENV !== 'test') {
app.use(csrf({ cookie: true }));
app.use(function(req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken());
return next();
});
}
测试CSRF
process.env.NODE_ENV = 'not_test';
var app = require("app.js");
var request = require('supertest')(app);
var testAccount = {
"login": "test",
"pass": "test"
};
describe('CSRF protection', function() {
it('On /login', function(done){
request
.post('/login')
.send(testAccount)
.expect(403, done);
});
});
测试登录 NODE_ENV现在是 test
process.env.NODE_ENV = 'test';
var app = require("app.js");
var request = require('supertest').agent(app);
var testAccount = {
"login": "test",
"pass": "test"
};
describe('API Admin roads', function() {
before(function (done) {
request
.post('/login')
.send(testAccount)
.end(done);
});
it('/api/admin/groups/', function(done){
request
.get('/api/admin/groups/')
.expect(200, done);
});
});
问题是,只考虑第一个process.env.NODE_ENV
,如果我将其设置为not_test
然后再设置为test
,我仍将处于not_test
模式。
答案 0 :(得分:0)
测试可以通过多种方式执行,它们的执行顺序并不总是相同(例如 mocha --parallel 选项)。
因此,重写 process.env
之类的共享变量并操作 require
缓存并不是解决此问题的可靠方法。这是一个黑客:今天它可以工作,但是当您(或您的同事)明天更改代码时,它很容易崩溃。
一种更简单、更简洁的方法是从您的 app.js
文件返回一个 init 函数,并获取 app
对象作为此函数调用的输出.通过这种方式,您可以向它传递一个显式选项来启用/禁用 csrf 令牌保护:
//app.js
module.exports = function appSetup(opts) {
var csrf = require('csurf');
var app = express();
if (opts.csrfEnabled) {
app.use(csrf({ cookie: true }));
app.use(function(req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken());
return next();
});
}
// more express handlers ...
// app.use(...)
return app;
}
然后,在没有 csrf 的测试中禁用它:
var app = require("app.js");
var request = require('supertest')(app({csrfEnabled: false}));
并在需要的地方启用:
var app = require("app.js");
var request = require('supertest')(app({csrfEnabled: true}));
显然你需要更新你的应用启动代码,例如bin/start.js
:
var app = require('../app')({csrfEnabled: true});
var server = http.createServer(app);
// and so on...
这种方法的优点: