ddo / oauth-1.0a

OAuth 1.0a Request Authorization for Node and Browser
MIT License
325 stars 116 forks source link

Headers are inconsistent and/or not forming correctly with access token and access token secret #111

Closed snovosel closed 3 years ago

snovosel commented 3 years ago

I am trying to post to the statuses/update route with the Twitter API.

Using the same credentials, literally copied and pasted from the below console log and put into Postman, this route works and I am returned a 200 from Twitter.

However, using axios and the below function will return an error code: 32, message: 'Could not authenticate you.' . I don't believe this is an issue with the Twitter API as the credentials are working with Postman. Could anyone offer some insight on this?

const publishTweet = async ({ tweetText, accessToken, accessTokenSecret }) => {
  try {
    const oauth = oauth1a({
      consumer: {
        key: process.env.TWITTER_OAUTH_CONSUMER_KEY, 
        secret: process.env.TWITTER_OAUTH_CONSUMER_SECRET
      },
      signature_method: "HMAC-SHA1",
      hash_function(base_string, key) {
        return crypto
          .createHmac("sha1", key)
          .update(base_string)
          .digest("base64");
      }
    });

   console.log('access tokens', {
       consumerKey: process.env.TWITTER_OAUTH_CONSUMER_KEY,
       consumerSecret: process.env.TWITTER_OAUTH_CONSUMER_SECRET,
       accessToken,
       accessTokenSecret
    });

    const twitterRequest = {
      url: `https://api.twitter.com/1.1/statuses/update.json?status=${tweetText}`,
      method: "POST",
    };

    const authorization = oauth.authorize(twitterRequest, accessTokens);
    const authHeader = oauth.toHeader(authorization);

    const twitterResponse = await axios.post(
      twitterRequest.url,
      {},
      { headers: authHeader }
    );

    console.log("twitterResponse", twitterResponse);
  } catch (error) {
    console.log("error publish tweet", error.response.data);
  }
};

I am using the same package and package method to generate the access token and access secret in step 1 of the oauth handshake without a problem. The issues are arising when the access token and access token secret are present in the signing process.

snovosel commented 3 years ago

For future reference, individual strings must be url encoded manually ie:

const twitterRequest = {
      url: `https://api.twitter.com/1.1/statuses/update.json?status=${encodeURIComponent(
        tweetText
      )}`,
      method: "POST"
    };
edsu commented 3 years ago

This bit me over here which is using URLSearchParams.set() to build up a URL and its query parameters. This works great, but when the parameter value contains a space it gets encoded as a + which causes oauth-1.0a to fail as described in this issue.