Twitter API authorization issues when creating unique parameters

Viewed 52

I am trying to create and post a tweet using the Twitter API. I have been using Postman to help create the API requests as per the instructions and walkthroughs on the Twitter API docs. When I am using Postman with hardcoded values everything works just fine and I can successfully post to twitter. The issue is when I try and create a unique signature to pass into the request, I get a 401(Unauthorized) from the twitter error response.

I follow the steps in the Twitter API docs at https://developer.twitter.com/en/docs/authentication/oauth-1-0a/creating-a-signature. And my outputs are identical in structure to the provided examples.

This is how I create the unique parameters:

To percentile encode the values I use encodeURIComponent()

oauth_nonce:

let OAUTH_NONCE = uuid.v1();

(uuid is one of many recommended way to create a random nonce, I have tried different ways but nothing works, also twitter says this can be any set of random alphanumerical strings)

oauth_timestamp:

let OAUTH_TIMESTAMP = Math.floor(Date.now() / 1000)

I create the parameter string like:

let parameterString = `include_entities=true&oauth_consumer_key=${CONSUMER_KEY}&oauth_nonce=${OAUTH_NONCE}&oauth_signature_method=${SIGNATURE_METHOD}&oauth_timestamp=${OAUTH_TIMESTAMP}&oauth_token=${ACCESS_TOKEN_KEY}&oauth_version=1.0&status=${encodedText}`

(The encoded text is percent encoded string that is being posted)

I then percent encode the parameter string and the base url which is ('https://api.twitter.com/2/tweets') to create a signature base string that looks like this

let signatureBaseString = `POST&${encodedURL}&${encodedParameterString}`

I create a signing key by encoding both the consumer secret token and access token secret

let signingKey = `${encodedConSecret}&${encodedOAuthSecret}`

I then use CryptoJS to create a hashed string:

let hash = CryptoJS.HmacSHA1(signatureBaseString, signingKey)

Then finally I create the signature like this:

let OAUTH_SIGNATURE = encodeURIComponent(Base64.stringify(hash))

I pass all that information into the config header for an axios post request. Here is my config for the headers:

  let config = {
    method: 'post',
    url: 'https://api.twitter.com/2/tweets',
    headers: { 
      'Authorization': `OAuth oauth_consumer_key="${CONSUMER_KEY}",oauth_token="${ACCESS_TOKEN_KEY}",oauth_signature_method="HMAC-SHA1",oauth_timestamp="${OAUTH_TIMESTAMP}",oauth_nonce="${OAUTH_NONCE}",oauth_version="1.0",oauth_callback="https%3A%2F%2F127.0.0.1",oauth_signature="${OAUTH_SIGNATURE}"`, 
      'Content-Type': 'application/json', 
    },
    data : data
  };

Here are two exampled of the headers taken from the Network tab in the chrome dev tools. One is a success with hardcoded values from Postman and the fail is from the unique parameters that I created. The consumer key and oauth token are removed for security sake.

SUCCESS from hard coded Postman:

OAuth oauth_consumer_key="CONSUMER_KEY",oauth_token="OAUTH_TOKEN",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1637279149",oauth_nonce="Ry6ldroxEyM",oauth_version="1.0",oauth_callback="https%3A%2F%2F127.0.0.1",oauth_signature="G7AoS6gk1MyI3Eoc6o%2F%2Bp8dM4o8%3D"

FAIL from created parameters:

OAuth oauth_consumer_key="CONSUMER_KEY",oauth_token="OAUTH_TOKEN",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1637279767",oauth_nonce="a8qgwtye6tw",oauth_version="1.0",oauth_callback="https%3A%2F%2F127.0.0.1",oauth_signature="an%2BpRdqwrqLsx9%2BS%2BrCqXY1omEw%3D"

Now I do not think its an issue with the signature, as I used the Twitter Doc example and got the same output as them, so the calculations for that seem to work just fine. My guess is that the problem is with the parameter string value, but I have tried a few different values but nothing seems to work. Again it works just fine with hardcoded values from Postman and I followed the examples and received similar outputs so I am a bit confused on why I receive the 401(Unauthorized) error. Any insight would be much appreciated, Thanks!

0 Answers
Related