"401 Request token failed" on HTTPS POST to oauth/request_token

oauth
authorization
authentication

#1

Per documentation I’m trying to request a request_token.

Do do this I need to send an oAuth signed header along with the request to oauth/request_token without the oauth_token parameter, as it is not yet known.

But using the generated header and signature returns response:

401 Request token failed

I’m confident the oAuth header and the signature are being generated correctly and in fact dropping vital comonents results in responses like:

401 {"errors":[{"code":32,"message":"Could not authenticate you."}]}

or

400 {"errors":[{"code":215,"message":"Bad Authentication data."}]}

I’ve tried all permutations of other suggestions of google results of this problem (including a blank oauth_token field, omitting oauth_version, matching header variable order to the parameter string order, always having oauth_signature as the last parameter) but none of these are working.

Can anybody advise where I’m going wrong?

Here’s an example with the secrets redacted (this permutation’s header order resmbles the example request here:
The oauth_callback matches the Callback URL set in the app settings.

======= oauth_test start =======

parameter_string (alphabetically sorted & encoded oauth params & values):
	oauth_callback=https%3A%2F%domain.com%2FoAuth_return&oauth_consumer_key=[CONSUMER_KEY]&oauth_nonce=tt4ofbgmnvp1n3jzia4i&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1513100616&oauth_version=1.0

signature_base_string (POST & encoded url & encoded parameter_string):
	POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3Dhttps%253A%252F%25domain.com%252FoAuth_return%26oauth_consumer_key%3D[CONSUMER_KEY]%26oauth_nonce%3Dtt4ofbgmnvp1n3jzia4i%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1513100616%26oauth_version%3D1.0

signing_key (ecoded consumer_secret & encoded oauth_token_secret (not yet known)):
	[consumer_secret]&

signature (sha1 hmac key:signing_key, update: signature_base_string, digest: base64):
	h0HKTLl7r7cthSc2dl+aBJRLpNA=

Authorization_header_str:
	oAuth oauth_nonce="tt4ofbgmnvp1n3jzia4i", oauth_callback="https%3A%2F%domain.com%2FoAuth_return", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1513100616", oauth_consumer_key="[CONSUMER_KEY]", oauth_signature="h0HKTLl7r7cthSc2dl%2BaBJRLpNA%3D", oauth_version="1.0"

thisHttpsOptions:
{
	host: 'api.twitter.com',
	path: '/oauth/request_token',
	method: 'POST',
	headers: {
		Authorization: 'oAuth oauth_nonce="tt4ofbgmnvp1n3jzia4i", oauth_callback="https%3A%2F%domain.com%2FoAuth_return", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1513100616", oauth_consumer_key="[CONSUMER_KEY]", oauth_signature="h0HKTLl7r7cthSc2dl%2BaBJRLpNA%3D", oauth_version="1.0"' 
	}
}

HTTPS request to:
	POST api.twitter.com/oauth/request_token

request finished with response:
	401 Request token failed

#2

I spent some time reading the source code of existing libraries.

Turns out, the Authorization header needs to start with OAuth not oAuth


#3

Which file(s) required making this change? I have been having a similar problem, and have had no luck in finding a solution.

Thank you.


#4

This is in a single file for test purposes. I just manually edited the Authorization header in the request.


#5

This is why it’s recommended to use established OAuth libraries instead of trying to roll your own… OAuth is very easy to get wrong.


#6

Absolutely would use an established library most of the time. Purpose here is to learn the intricacies though so was important to get into the weeds.

Also discovered that the Twitter docs describing the signature appear to be wrong.

Example for building the base string indicate the GET params should be included in the URL part, but this results in an invalid base string.