So I am trying to make authenticated calls to the API, but am getting error code 32: “Could not authenticate you.” I’ve read through the forums here and it seems the most common problem is percent encoding and parameter ordering. I also know I should be using a library and I plan to next time, but I’m so close now and want to understand what is happening behind the scenes anyway. Here’s my Node JS code to call users/show:

I am using the nonce and query-string modules.

  const user = 'twitterdev';
  const state = nonce();
  const timeStamp = Math.floor((new Date()).getTime() / 1000);

  var params = {
    screen_name: user,
    oauth_consumer_key: APP_KEY,
    oauth_nonce: state,
    oauth_signature_method: 'HMAC-SHA1',
    oauth_timestamp: timeStamp,
    oauth_version: '1.0'
  }

  var oauthSignature = createSignature('GET', SHOW_URL, params);

  var headerString = 'OAuth ' + encodeURIComponent('oauth_consumer_key') + '="' + encodeURIComponent(APP_KEY) + '", ' + encodeURIComponent('oauth_nonce') + '="' + encodeURIComponent(state) + '", ' + encodeURIComponent('oauth_signature') + '="' + encodeURIComponent(oauthSignature) + '", ' + encodeURIComponent('oauth_signature_method') + '="' + encodeURIComponent('HMAC-SHA1') + '", ' + encodeURIComponent('oauth_timestamp') + '="' + encodeURIComponent(timeStamp) + '", ' + encodeURIComponent('oauth_version') + '="' + encodeURIComponent('1.0') + '"';

  var options = {
    url: SHOW_URL,
    headers: {
      'authorization': headerString
    },
    qs: {
      'screen_name': user,
    },
    json: true
  };

  request(options, function(error, response, body) {
    if (!error && response.statusCode == 200) {

      console.log('User:', response.body);

    } else if (response.statusCode == 404) {
      console.log('User not found?');
      if (body.errors) {
        console.log(body.errors[0]);
      }  
    } else {
      if (error) {
        console.log('Error: ', error);
      }
      console.log('Body error: ', body);
      console.log('Status code: ' + response.statusCode);
      //console.log(response.headers);
    }
  });

  function createSignature(method, baseUrl, params) {

  // sorts the keys and converts to query string, URI encoded (percent encoded)
  const paramsString = querystring.stringify(params);

  var signatureBaseString = method.toUpperCase() + '&' + encodeURIComponent(baseUrl) + '&' + encodeURIComponent(paramsString);

  var signingKey = encodeURIComponent(APP_SECRET) + '&' + encodeURIComponent(APP_TOKEN_SECRET);

  const generatedHash = crypto
    .createHmac('sha256', signingKey)
    .update(signatureBaseString)
    .digest('base64');

  return generatedHash;

  }

When I print my data to the console at various stages (encoding parameters, signature, etc) it appears as though they are correctly encoded. You may also notice I do not have the oauth_token in my parameters, that’s because it is not required for this API call. Nonetheless I’ve tried including it too, and still get the same error.

Here’s what I see when I print out my request header:

{ authorization:
‘OAuth oauth_consumer_key=“HIDDEN”, oauth_nonce=“158222620297900”, oauth_signature=“3Q6%2FLYSDibRSD6nt80mNfDSZqmmo%2BwSetJ4hbjIeA3Y%3D”, oauth_signature_method=“HMAC-SHA1”, oauth_timestamp=“1582226202”, oauth_version=“1.0”’,
host: ‘CANT_SHOW_LINKS_IN_POST’,
accept: ‘application/json’ }

What am I missing? Am I hashing the secrets incorrectly? is encodeURIComponent not encoding correctly?

If you are using OAuth 1 than a users token and secret is required. If you want to use Application Auth without a user context that would be much simpler to implement.

1 Like

I have successfully called this API endpoint using a Bearer Token, but I am now trying to do it in a user context, to make sure I’ve got everything right before implementing other calls into my app. But are you implying that it will not work to pass my application’s token and token secret? (Which is of course different from my API Key and API Secret). And that it has to be an individual user’s token?

To make an API request using OAuth 1 in a user context you need two token pairs.

  • The API key and API secret key from the Twitter Apps dashboard (these are called Consumer Key and Consumer Secret in OAuth parlance)
  • A user’s Access Token and (Access) Token Secret (either from the Twitter Apps dashboard or from the 3-legged oauth flow.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.