ciaranj/node-oauth

Receiving error: "status":342

Closed this issue · 2 comments

Hi all, I've been running some code that gets measurement data via Nokia API for months now, but sometime in mid-February it started hitting this error: {"status":342,"body":{},"error":"The signature (using Oauth) is invalid"} for every user I try to get data for.

Here's the gist of the code. The function below is used in a loop of user tokens/secrets to get their data.

function processUser(user, option) {
	var oauth = require("oauth");
		var withings = new oauth.OAuth(
			"https://developer.health.nokia.com/account/request_token",
			"https://developer.health.nokia.com/account/access_token",
			user.ckey,
			user.csecret,
			"1.0",
			null,
			"HMAC-SHA1"
		);
		var url = withings.signUrl(`
                  http://api.health.nokia.com/v2/measure?action=getactivity&startdateymd=2017-06-15&enddateymd=${today}&userid=${user.Userid}`, 
                  user.otoken, 
                  user.osecret
                );
		withings.get(url, null, null, function(error, response) {
                  ...Do things with the response
                }
}

Did something change in Nokia's API that I need to change this code for? If others aren't seeing this error then maybe I can change something to get it working again.

I think, the problem is in OAuth.prototype._prepareParameters in oauth.js

After calling signUrl (which uses _prepareParameters) the parameter 'oauth_signature' is already in the extra_params. So when calling get (which calls _prepareParameters again) the signature is calculated inclusive the first 'oauth_signature' and it appends another new parameter 'oauth_signature which ist incorrect.
Excluding the 'oauth_signature' in prepareParameters helps for me. See the new two lines:

   if( parsedUrl.query ) {
      var key2;
      var extraParameters= querystring.parse(parsedUrl.query);
      for(var key in extraParameters ) {
        /* NEW */ if (key !== 'oauth_signature') { /* dont calculate signature with oauth_signature */**
          var value= extraParameters[key];
          if( typeof value == "object" ){
            // TODO: This probably should be recursive
            for(key2 in value){
              oauthParameters[key + "[" + key2 + "]"] = value[key2];
            }
          } else {
            oauthParameters[key]= value;
          }
        /* NEW */  }
      }
    }
 

Thank you for the reply!

Update:
I found that the url produced by

var url = withings.signUrl(`
                  http://api.health.nokia.com/v2/measure?action=getactivity&startdateymd=2017-06-15&enddateymd=${today}&userid=${user.Userid}`, 
                  user.otoken, 
                  user.osecret
);

works by itself, so I instead used the request package to get from that URL and it works just fine.

Per the docs it seems like the signUrl part is unnecessary and I should be able to do something like

var url = http://api.health.nokia.com/v2/measure?action=getactivity&startdateymd=2017-06-15&enddateymd=${today}&userid=${user.Userid};

withings.get(url, user.otoken, user.osecret, function(error, response) {
                  ...Do things with the response
}

But I tried that and it didn't work. To me this signals that something may be wrong with this package's .get() method.