【问题标题】:How to test http api that uses csurf csrf protection with mocha/chai?如何使用 mocha/chai 测试使用 csurf csrf 保护的 http api?
【发布时间】:2022-01-24 00:54:40
【问题描述】:

不是this one的重复项

我想知道为了测试使用 csurf csrf 保护的 api 需要设置的最小标头/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,但由于中间件的 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
}

【问题讨论】:

    标签: node.js automated-tests csrf chai chai-http


    【解决方案1】:

    根据documentation,令牌应该在一个名为CSRF-Token的标头中。

    request(app)
      .post('/singup')
      .set('CSRF-Token', _csrf)
    ...
    

    此外,您可能需要在请求中设置Cookie 标头。但是您应该使用第一个请求的响应中的 Set-Cookie 标头的值。

    为此,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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      • 2017-08-25
      • 2013-04-11
      • 2017-10-08
      • 1970-01-01
      相关资源
      最近更新 更多