简体   繁体   中英

Node.js - req.on(“data”) in POST is never called even though req.body is not empty

I'm doing the following :

......
....
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({  
  extended: true 
})); 

app.use('/public', express.static(__dirname + '/public'));

app.post('/uninstalled', function (req, res, next)
{     
  var bodyAsQueryString = queryString.stringify(req.body);
  console.log('bodyAsQueryString = ' + bodyAsQueryString);

  var hmacReceived = req.headers['x-shopify-hmac-sha256'];
  var calculatedHmac = crypto.createHmac('SHA256', config.app.secret);

  req.on("data", function(data) 
  {
     console.log('on data...');
     calculatedHmac.update(data);
  });

  req.on("end", function() 
  {
     console.log('on end...');
     calculatedHmac = calculatedHmac.digest("base64");
     console.log('hmacReceived = ' + hmacReceived);
     console.log('calculatedHmac = ' + calculatedHmac);
  });

  req.on("error", function(err) 
  {
     console.log('on error...');
     console.log(err);
     return next(err);
  });
});

None of the above req.on("...") is ever called (nothing is console-logged...) - What am I doing wrong ?

The value of bodyAsQueryString always looks smth like the following (I've replaced personal data with xxxxx ) :

id=xxxxx&name=xxxxx&email=xxxxxx&domain=xxxxxxx&created_at=2015-03-21T00%3A31%3A36%2B00%3A00&province=&country=GB&address1=xxxxxxxxx&zip=E59JY&city=London&source=xxxx&phone=xxxxxx&updated_at=2015-08-19T15%3A12%3A31%2B01%3A00&customer_email=&latitude=xxxxx&longitude=-xxxxxx&primary_location_id=&primary_locale=en&country_code=GB&country_name=United%20Kingdom&currency=USD&timezone=(GMT%2B00%3A00)%20Europe%2FLondon&iana_timezone=Europe%2FLondon&shop_owner=xxxxxx&money_format=%24%20%7B%7Bamount%7D%7D&money_with_currency_format=%24%20%7B%7Bamount%7D%7D%20USD&province_code=&taxes_included=false&tax_shipping=&county_taxes=true&plan_display_name=affiliate&plan_name=affiliate&myshopify_domain=xxxxxx.myshopify.com&google_apps_domain=&google_apps_login_enabled=&money_in_emails_format=%24%7B%7Bamount%7D%7D&money_with_currency_in_emails_format=%24%7B%7Bamount%7D%7D%20USD&eligible_for_payments=false&requires_extra_payments_agreement=false&password_enabled=true&has_storefront=true&setup_required=false

You need to use the raw POST body rather than req.body.

Try something like this:

app.post('/somepath', function (req, res, next) {
    var hmacReceived = req.headers['x-shopify-hmac-sha256'];
    hmac = crypto.createHmac('SHA256',secret);

    req.on("data", function(data) {
        hmac.update(data);
    });

    req.on("end", function() {
        var calculatedHmac = hmac.digest("base64");
        var test1 = hmacReceived === calculatedHmac;
    });

    req.on("error", function(err) {
        return next(err);
    });
}

Further details in this similar question:

HMAC MD5 Validation with Node.js, Express and Trialpay

Turns outs it's because I wasn't replying to the client anywhere in the callback with something like:

res.sendStatus(200); or res.sendStatus(500); etc...

It's weird because my the code in my callbacks executes fine (even without ever replying to the client) but apparently if the node parser realises there is a req.on() and no reply to the client, either inside or outside of it, it will ignore the req.on(..) which makes no sense really... Either the whole thing should break or none of it if a reply to the client is missing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM