mckelvey / instagram-node-lib

The Instagram Node Lib is a helper library for node that makes communicating with the Instagram API easy.
http://david.mckelveycreative.com/
Other
303 stars 49 forks source link

Missing req.rawBody for Instagram.subscriptions.verified(req) #6

Closed PatrickHeneise closed 3 years ago

PatrickHeneise commented 12 years ago

The new version of express/connect doesn't support rawBody any more. What's the best way to get the raw body and verify it?

TypeError: Not a string or buffer at InstagramSubscriptions.verified (/data/apps/abc/node_modules/instagram-node-lib/lib/class.instagram.subscriptions.js:44:12) at instagram.js:9:39

mckelvey commented 12 years ago

Thanks Patrick — I’ll take a look and see what other options might exist. Until then you might stay on express 2.x; 3.0 is still in beta (but like you, I’ve also ended up with it loaded too).

PatrickHeneise commented 12 years ago

I tried something like this before bodyParser():

app.use(function(req, res, next) {
  if (0 == req.url.indexOf('/api')) {
    console.log('setting rawBody');
    var data='';
    req.setEncoding('utf8');

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

    req.on('end', function() {
      console.log('data: ', data);
      req.rawBody = data;
      next();
    });
  } else {
    next();
  }
});

But that didn't work properly.

mckelvey commented 12 years ago

@PatrickHeneise — I’ve been looking into this but can’t replicate in my tests yet. Tell me, does this comment help?

PatrickHeneise commented 12 years ago

The posted middleware is pretty much the same as in the comment and doesn't work.

The question is related to Instagram.subscriptions.verified(req), which checks req.rawBody for the HMAC response from Instagram to verify the data is really coming from Instagram. As said, it just doesn't work with Express >3.0 any more.

app.get('/api/instagram/callback', function(req, res) { Instagram.subscriptions.handshake(req, res); });

app.post('/api/instagram/callback', function(req, res){ console.log(Instagram.subscriptions.verified(req)); });

This minimum example should throw an error already when an Instagram callback comes in.

nathanbowser commented 12 years ago

I looked into this a bit. I have this module working with express3 and subscription updates. I'm not calling Instagram.subscriptions.verified(req) and just handling things myself.

mckelvey commented 12 years ago

@nathanbowser I’ll be looking at making a fix over the weekend, if you wouldn’t mind sharing your solution I’ll see if I can work it in to fix verify.

nathanbowser commented 12 years ago

I didn't look into it deep enough to figure out why you need to call that verify function. If you simply fire a res.json {ok: true} or res.send 'Alive and well', I think that''s enough to make their API happy. Do that right away, though. In your POST callback, fire an async function to process the request and go get the actual data. Then return a status okay message.

mckelvey commented 12 years ago

Gotcha — I admit the risk that someone else would ping your callback address is minimal, so bypassing the check is a reasonable option. I’ll still dig on the weekend to see if I can get to the raw response. :)

PatrickHeneise commented 12 years ago

@nathanbowser you need to send the handshake to Instagram to verify your server and you can verify the response with the verify function. The risk is indeed low, but it's a direct link into the system and should be verified, I think. At the moment I'm just not verifying and everything is fine but for production use I'd prefer to do that.

PatrickHeneise commented 12 years ago

I tried several things to get to the rawBody without success so far. I guess the middleware is the only solution. I'll try that again later.

mckelvey commented 12 years ago

@PatrickHeneise let me know if you make any headway. My next plan is to see if I could take the callback out of Express’s handling and use connect directly to get the raw content if I can’t get Express to save a copy.