I've been using Postman to making an object that I need to include in a axios request that uses OAuth1.0, Postman does it successfully. Now I'm attempting to do it without Postman so that I can automate things but I'm having trouble using OAuth1.0. I am using the npm package oauth1.0a and have installed my necessary dependencies like crypto. I am successfully putting the Authorization header in the right place for the request, but when I log it, it looks different from Postman, and the parameters are in a different order. The documentation that I have read for Oauth1.0a seems to indicate that order matters, so I am not sure why mine is coming out of order. This is what the authorization header is supposed to look like:
'Authorization': 'OAuth oauth_consumer_key="XXX",oauth_token="XXX",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1559312415",oauth_nonce="XXX",oauth_version="1.0",oauth_signature="XXX"'
and this is what mine is coming out as (note the difference in order):
Authorization: 'OAuth oauth_consumer_key="XXXXXX",oauth_nonce="XXXXX",oauth_signature="XXXXXX",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1709321223",oauth_token="XXXXX",oauth_version="1.0"'
Does the order matter? If so, how do I correct it? Is there anything else wrong with what I am doing?
I have referenced this post for help: OAuth1.0 header in Node.js
I have tried to manipulate the authorization header string and put things in order. I have double and triple checked my consumer keys and tokens, and they are correct because Postman is using those and those requests are successful. I have tried to make my code match Postman as much as possible. I have changed parameters in my OAuth instance (', ' vs '' between params), as well as the length of the nonce (Postmans oauth_nonce is 11 characters). Have also referenced the Twitter API documentation here: https://developer.twitter.com/en/docs/authentication/oauth-1-0a/authorizing-a-request. Have also asked ChatGPT for it's understanding of the problem.
Here's the relevant code with some portions abstracted away:
let data = JSON.stringify({
"text": "Hello World!"
});
const OAuth = require('oauth-1.0a');
const crypto = require('node:crypto');
// const crypto = import('node:crypto');
const oauth = OAuth({
consumer: {
key: '<key>',
secret: '<secret>'
},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return crypto.createHmac('sha1', key).update(base_string).digest('base64');
},
// nonce_length: 11,
parameter_seperator: ','
});
const token = {
key: '<tokenkey>',
secret: '<tokensecret>'
}
let request = {
url: 'https://api.twitter.com/2/tweets',
method: 'POST',
data: data
}
let authorization = oauth.authorize(request, token);
let headers = oauth.toHeader(authorization);
let config = {
method: 'post',
maxBodyLength: Infinity,
url: 'https://api.twitter.com/2/tweets',
headers: {
'Content-Type': 'application/json',
'Authorization': `${headers.Authorization}`,
'Cookie': 'guest_id=xxx; guest_id_ads=xxx; guest_id_marketing=xxx; personalization_id="xxx"'
},
data : data
};
axios.request(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error.message);
});
I missed an error in the request object. Instead of having a "body" attribute, I erroneously put a "data" attribute. This body attribute is required for the request object to be used properly by the OAuth instance. As for if the order matters, I have seen some say it does, and others say it doesn't. I implemented a function that changed the order of the authorization string, so I still don't know definitively in this instance. I am leaning toward the option that it does not matter. Press on.