Search code examples
javascriptnode.jskoa

Access the raw body of a request in koa.js


I have created an API using io.js and koa.js.

As a body parser middleware I am using koa-body, which in turn uses co-body.

On one of my API endpoints I am receiving POST requests, and I need access to the raw body of the request, because I need to encode it to verify if the request is valid.

Is there any way to access the raw body of the request? I tried to use the raw-body middleware, but if I use it before I call koa-body, the co-body used in koa-body breaks. If I use it after koa-body it does not work.

   app.use(function*(next){
    let rawRequestBody = yield rawBody(this.req);
    this.rawRequestBody = rawRequestBody;

    yield next;
  });

EDIT:

I think that I found a workaround, but I don't know if this is the best solution. I think that @greim answer may be a better solution to this problem.

I added the following code before I use koa-body:

app.use(function *(next) {

    let url = this.req.url;

    if(this.req.method == 'POST') {
      let that = this;
      this.req.rawBody = '';

      this.req.on('data', function(chunk) {
        that.req.rawBody += chunk;
      });
    }

    yield next;
  });

Solution

  • It only makes sense to capture the stream once.

    You can capture the request body as a string or buffer (I assume this is what you mean by "raw" body) using the raw-body utility, and then keep a reference to it as shown in your own code, such that:

    let rawRequestBody = yield rawBody(this.req);
    this.rawRequestBody = rawRequestBody;
    console.log(typeof this.rawRequestBody); // "string"
    

    Once you do that, don't also use koa-body or co-body, since those are also stream-capturing utilities which assume you haven't yet captured the stream. To make the request body accessible as JSON (for example) simply do this:

    this.jsonRequestBody = JSON.parse(this.rawRequestBody);
    console.log(typeof this.jsonRequestBody); // "object"