views:

4197

answers:

10

I am trying to use Twitter OAuth and my POST requests are failing with a 401 (Invalid OAuth Request) error.

For example, if I want to post a new status update, I am sending a HTTP POST request to https://twitter.com/statuses/update.json with the following parameters -

status=Testing&oauth_version=1.0&oauth_token=xxx&
oauth_nonce=xxx&oauth_timestamp=xxx&oauth_signature=xxx&
oauth_consumer_key=xxx&in_reply_to=xxx&oauth_signature_method=HMAC-SHA1`

My GET requests are all working fine. I can see on the mailing lists that a lot of people have had identical problems but I could not find a solution anywhere.

I am using the oauth.py Python library.

+1  A: 

Most likely, the signature is invalid. You must follow the OAuth spec on how to generate the signature( normalized parameters, URLencoding, and cosumerSecret&oauthScret. More on this later ......

Mike
Later? When/where is later?
Rizwan Kassim
+2  A: 

I just finished implementing twitter OAuth API from scratch using Java. Get and post requests work OK. You can use this page http://www.hueniverse.com/hueniverse/2008/10/beginners-gui-1.html to check signature and HTTP headers. Just enter your keys and tokens and check output. It seems twitter works exactly as described on this post. Be careful with spaces and UTF-8 symbols, for example Java encodes space as "+" but OAuth requires %20

A: 

I wonder if you've found a solution to this? I'm having the same problem. My GET requests are fine, but POST always returns 401 error

I tried both http: and https

Mariatta
Yes. Make sure you include the Http method name when you sign the payload. I missed out the name of the method while POST-ing.
Baishampayan Ghose
+2  A: 

I had the same issues, until I realised that the parameters need to be encoded twice for the base string. My GET requests all worked fine, but my POSTs, particularly status updates, failed. On a hunch I tried a POST without spaces in the status parameter, and it worked.

In PHP:

function encode($input) {
    return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($input)));
}

$query = array();
foreach($parameters as $name => $value) {
    $query[] = encode($name) . '=' .encode($value);
}
$base = encode(strtoupper($method)) . '&' .encode($norm_url) . '&' . 
encode(implode('&', $query));

Notice the encode function around the names and values of the parameters, and then around the whole query string. A Space should end up as %2520, not just %20.

Jrgns
Maybe this just saved my day. I'm having the exact same problem, only in JavaScript. GET works, POST not so much ...
Techpriester
+1  A: 

Make sure your app access type is read & write. On your app settings page (ex. http://twitter.com/apps/edit/12345) there's a radio button field like this:

Default Access type: Read & Write / Read-only

If you check 'Read-only' then status update API will return 401.

Nobu
A: 

I am also facing the same issue. my all get requests are working perfectly all right, but get an error of 'Invalid Signature' on post requests.

although I am using the same method to create signature for get requests as well as post requests. I am googling it for around three hours, but still unable to find the solution :(

Zain Shaikh
A: 

I have this problem too. "incorrect signature" when post status. but authorize work fine.

durm
A: 

"incorrect signature" solved for me:

in update url using https instead of http

durm
A: 

Once an app is read only it will not be able to write ( even if it is changed in the settings ), you'll need to setup a new app and be sure to choose read & write at creation.

A: 

I found the solution and it works for me, You must add the following paramters in the request header and it should look like following (c# code), donot use & sign, instead separate parameters by comma(,) sign. and you must add the word "OAuth" in the beginging.

httpWebRequest.Headers[System.Net.HttpRequestHeader.Authorization] = "OAuth oauth_consumer_key=\"hAnZFaPKxXnJqdfLhDikdw\", oauth_nonce=\"4729687\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1284821989\", oauth_token=\"17596307-KH9iUzqTxaoa5576VjILkERgUxcqExRyXkfb8AsXy\", oauth_version=\"1.0\", oauth_signature=\"p8f5WTObefG1N9%2b8AlBji1pg18A%3d\"";

and other parameters like 'status' should be written in the body of the request.

Zain Shaikh