如何测试使用 mocha/chai 的 csurf csrf 保护的 http api?
How to test http api that uses csurf csrf protection with mocha/chai?
不是 this one
的副本
我想知道要测试使用 csurf csrf 保护的 api 需要设置的最低 headers/cookies 是多少。
在我的服务器中我有:
const app = express()
const csrfMiddleware = csurf({
cookie: true
})
app.use(cookieParser())
app.use(csrfMiddleware)
app.get('/singup', ...)
app.post('/singup', ...)
在测试文件中:
const chai = require('chai')
const chaiHttp = require('chai-http')
chai.use(chaiHttp);
const request = chai.request;
const expect = chai.expect;
const cheerio = require('cheerio')
const app = "http://localhost:3000"
function extractCsrfToken(res) {
var $ = cheerio.load(res.text);
return $('[name=_csrf]').val();
}
describe('Post Endpoints', () => {
it('should create a new user', () => {
request(app).get('/singup').end((err, resGet)=>{
expect(err).to.be.null;
expect(resGet).to.have.status(200)
const _csrf = extractCsrfToken(resGet);
console.log(`sending request with csrf token ${_csrf}`)
request(app)
.post('/singup')
.set('Cookie', `_csrf=${_csrf}`)
.set('Connection', 'keep-alive')
.set('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8')
.send({
username: "teste-automatizado",
email: 'some-email@example.com',
password: '12345678',
passwordConfirm: '12345678'
}).end((err2, res)=>{
expect(err2).to.be.null;
expect(res).to.have.status(200)
})
})
})
})
我期望的是创建用户和来自 POST 请求的 200 return 这没有发生,因为它失败了来自中间件的 403:
$ npm test
> app@1.0.0 test
> mocha
Post Endpoints
✔ should create a new user
1 passing (21ms)
sending request with csrf token PDwitHYN-ttgB5zAIGCQqq9cCxgwkbXyyrMM
/home/fabio/src/project/node_modules/mocha/lib/runner.js:962
throw err;
^
AssertionError: expected { Object (_events, _eventsCount, ...) } to have status code 200 but got 403
at /home/fabio/src/project/test.js:37:33
at Test.Request.callback (/home/fabio/src/project/node_modules/superagent/lib/node/index.js:716:12)
at IncomingMessage.<anonymous> (/home/fabio/src/project/node_modules/superagent/lib/node/index.js:916:18)
at IncomingMessage.emit (node:events:402:35)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
showDiff: true,
actual: 403,
expected: 200
}
根据 documentation,令牌应位于名为 CSRF-Token
的 header 中。
request(app)
.post('/singup')
.set('CSRF-Token', _csrf)
...
此外,您可能需要根据第一个请求的响应设置 Cookie header on your request. But you should use the value of the Set-Cookie header。
为此,chai 可以选择 retain the cookies。关键是使用代理来发出所有请求。
const agent = chai.request.agent(app)
agent.get('/singup').end((err, res) => {
// do some tests and get the token
// ...
// the agent will use the cookie from the previous request
// so you only need to set the CSRF-Token header
agent.post('/singup')
.set('CSRF-Token', _csrf)
.send({ username: 'me', password: '123' })
.end((err, res) => {
// handle the post response
})
})
agent.close()
不是 this one
的副本我想知道要测试使用 csurf csrf 保护的 api 需要设置的最低 headers/cookies 是多少。
在我的服务器中我有:
const app = express()
const csrfMiddleware = csurf({
cookie: true
})
app.use(cookieParser())
app.use(csrfMiddleware)
app.get('/singup', ...)
app.post('/singup', ...)
在测试文件中:
const chai = require('chai')
const chaiHttp = require('chai-http')
chai.use(chaiHttp);
const request = chai.request;
const expect = chai.expect;
const cheerio = require('cheerio')
const app = "http://localhost:3000"
function extractCsrfToken(res) {
var $ = cheerio.load(res.text);
return $('[name=_csrf]').val();
}
describe('Post Endpoints', () => {
it('should create a new user', () => {
request(app).get('/singup').end((err, resGet)=>{
expect(err).to.be.null;
expect(resGet).to.have.status(200)
const _csrf = extractCsrfToken(resGet);
console.log(`sending request with csrf token ${_csrf}`)
request(app)
.post('/singup')
.set('Cookie', `_csrf=${_csrf}`)
.set('Connection', 'keep-alive')
.set('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8')
.send({
username: "teste-automatizado",
email: 'some-email@example.com',
password: '12345678',
passwordConfirm: '12345678'
}).end((err2, res)=>{
expect(err2).to.be.null;
expect(res).to.have.status(200)
})
})
})
})
我期望的是创建用户和来自 POST 请求的 200 return 这没有发生,因为它失败了来自中间件的 403:
$ npm test
> app@1.0.0 test
> mocha
Post Endpoints
✔ should create a new user
1 passing (21ms)
sending request with csrf token PDwitHYN-ttgB5zAIGCQqq9cCxgwkbXyyrMM
/home/fabio/src/project/node_modules/mocha/lib/runner.js:962
throw err;
^
AssertionError: expected { Object (_events, _eventsCount, ...) } to have status code 200 but got 403
at /home/fabio/src/project/test.js:37:33
at Test.Request.callback (/home/fabio/src/project/node_modules/superagent/lib/node/index.js:716:12)
at IncomingMessage.<anonymous> (/home/fabio/src/project/node_modules/superagent/lib/node/index.js:916:18)
at IncomingMessage.emit (node:events:402:35)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
showDiff: true,
actual: 403,
expected: 200
}
根据 documentation,令牌应位于名为 CSRF-Token
的 header 中。
request(app)
.post('/singup')
.set('CSRF-Token', _csrf)
...
此外,您可能需要根据第一个请求的响应设置 Cookie header on your request. But you should use the value of the Set-Cookie header。
为此,chai 可以选择 retain the cookies。关键是使用代理来发出所有请求。
const agent = chai.request.agent(app)
agent.get('/singup').end((err, res) => {
// do some tests and get the token
// ...
// the agent will use the cookie from the previous request
// so you only need to set the CSRF-Token header
agent.post('/singup')
.set('CSRF-Token', _csrf)
.send({ username: 'me', password: '123' })
.end((err, res) => {
// handle the post response
})
})
agent.close()