POST request returned {"message":"Could not authenticate you","code":32} after migrated to API v1.1


#1

We migrate our app from API v1.0 to API v1.1.

Only one line of code we modified for example is from

https://api.twitter.com/1/statuses/update.json

to

https://api.twitter.com/1.1/statuses/update.json

The server will return

{"message":"Could not authenticate you","code":32}

Detail difference of these two requests is here: http://www.mergely.com/nAotEsme/

All of our POST request would failed after migrate to API v1.1 but GET requests still work fine.

Is there anything else that we need to modify?

Thanks for replying in advance.


#2

OK… root cause found…

Need to add a HTTP header after migrate to API 1.1

Content-Type: application/x-www-form-urlencoded


#3

I already have my HTTP header. But am still receiving the same error.
I’m only Authenticating for my own ID, and here is the code I’m using to build my signature and my HTTP header:

$oauth = array( ‘oauth_consumer_key’ => $consumer_key,
‘oauth_nonce’ => time(),
‘oauth_signature_method’ => ‘HMAC-SHA1’,
‘oauth_token’ => $oauth_access_token,
‘oauth_timestamp’ => time(),
‘oauth_version’ => ‘1.0’);

/-------Create OAuth signature -----------/
$base_info = buildBaseString($url, ‘GET’, $oauth);
$composite_key = rawurlencode($consumer_secret) . ‘&’ . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac(‘sha1’, $base_info, $composite_key, true));
$oauth[‘oauth_signature’] = $oauth_signature;

/-------Set up HTTP header --------/
$header = array(buildAuthorizationHeader($oauth), ‘Expect:’);
$options = array( CURLOPT_HTTPHEADER => $header,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);

$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

It’s completely stopped working under V1.1 & I’m desperately looking to solve it…


#4

I had exactly the same issue. You won’t believe that, but adding the post data to the query string instead of the post body solves the issue. That sound awkward, but it works.


#5

This will not work on stream endpoints with long queries.
E.g. many tracks, follows and geo locations on the public stream endpoint when the query exceeds the length limit of GET.


#6

I’m also having the same issue failed to tweet. Adding the Content-Type: application/x-www-form-urlencoded header will cause a {“errors”:[{“message”:“Could not authenticate you”,“code”:32}]}.

===request===

POST https://api.twitter.com/1.1/statuses/update.json HTTP/1.1
Authorization: OAuth oauth_consumer_key=“iZK5PTMB35Kq4Yc6vcemZw”, oauth_nonce=“e6b569107f7771739b0c9aa290635d35”, oauth_signature=“sw7R1h5Q4MVdyM76XchYpJc16bY%3D”, oauth_signature_method=“HMAC-SHA1”, oauth_timestamp=“1354238620”, oauth_token=“979339014-SoyWtkAXsAgyLDssNXL1SgMHj5Ez5sZvLDDQsT3K”, oauth_version="1.0"
Host: api.twitter.com
Content-Length: 25
Expect: 100-continue
Connection: Keep-Alive

status=aaaaaaaaaaaaaaa

===response===

HTTP/1.1 403 Forbidden
Date: Fri, 30 Nov 2012 01:24:59 GMT
Status: 403 Forbidden
X-Transaction-Mask: a6183ffa5f8ca943ff1b53b5644ef114b28557d5
Content-Length: 72
X-Frame-Options: SAMEORIGIN
X-MID: 06628407723f317d097bad95bbcce5f3ccd36ad5
Pragma: no-cache
X-Access-Level: read-write
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
X-Transaction: 40294b9f235b7c49
Content-Type: application/json; charset=utf-8
Last-Modified: Fri, 30 Nov 2012 01:24:59 GMT
X-Runtime: 0.03509
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Set-Cookie: k=10.35.64.136.1354238699459986; path=/; expires=Fri, 07-Dec-12 01:24:59 GMT; domain=.twitter.com
Set-Cookie: guest_id=v1%3A135423869946461453; domain=.twitter.com; path=/; expires=Sun, 30-Nov-2014 13:24:59 GMT
Set-Cookie: dnt=1; domain=.twitter.com; path=/; expires=Wed, 30-Nov-2022 13:24:59 GMT
Set-Cookie: pid=; domain=.twitter.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT
Set-Cookie: lang=en; path=/
Set-Cookie: lang=en; path=/
Set-Cookie: lang=en; path=/
Set-Cookie: twid=u%3D979339014%7C5te4iim72CrVxPT8ls7cKk2Xelo%3D; domain=.twitter.com; path=/; secure
Set-Cookie: _twitter_sess=BAh7CToMY3NyZl9pZCIlMjQ4M2E3N2YxZTUwNTQwNjc1YTQxZmRhYjY3NjMy%250AZGY6D2NyZWF0ZWRfYXRsKwjZp%252BpOOwEiCmZsYXNoSUM6J0FjdGlvbkNvbnRy%250Ab2xsZXI6OkZsYXNoOjpGbGFzaEhhc2h7AAY6CkB1c2VkewA6B2lkIiU3MmM2%250AMzY0OGI1MTU0OGZkNDU5NDQ0ZTQ2MGViODZmOQ%253D%253D–b57cd328c4409504c6272a8f78445b42f8bc67c3; domain=.twitter.com; path=/; HttpOnly
Vary: Accept-Encoding
Server: tfe

{“errors”:[{“code”:170,“message”:“Missing required parameter: status”}]}


#7

I’ve run into this on 1.1 as well, with any status that contains an apostrophe or a few other special characters, even though they’re encoded and my signature base matches the Twitter OAuth tool’s. Reverting to 1 works fine.


#8

i have the same issues with search/tweets when migrating to 1.1

query without special character works, adding any special characters like ‘+’ returns {“message”:“Could not authenticate you”,“code”:32}

reverting to 1.0 works flawlessly

EDIT: what helped me eventually is this thread: https://dev.twitter.com/discussions/10935

i had a double url encoding of the same string which lead encoding qotes to %2522 instead of %22… solving this helped


#9

Thank you.

I patched my OAuth library, I solved this problem.
But I think it is not universal because other OAuth service provider doesn’t have this rule and I cannot use this patched library for any other services.

This spec or problem is mentioned in Twitter document?
I want to know if this spec will be changed or not until we can’t use 1.0 version of API.


#10

i have the same issue.
???


#11

I was getting the same error but for me it was a simple issue. I did not pay careful enough attention to the documentation. When building the “signature base string” the values must be in strict alphabetical order - so this includes the name/value pairs you are including in your query string (GETs) or post data (POSTs). I wasn’t doing this, so some of my API calls worked and some didn’t - purely by fluke (if I happened by chance it include them in the correct order).

When I ensured that they were in order then it all worked fine. I found it my just using the oauth tool for the API in question to generate the example signature, header and HTTP request, then comparing it to the versions my software was generating. It stood out like a sore thumb then.


#12

for your information.


#13

68


#14

Same issue 37 weeks after being first reported. Why is Twitter staff doing NOTHING? If you don’t seriously think about providing support to developers, why don’t you just close down this unfriendly platform? I’m exhausted trying to find some help…


#15

Same issue here - code 32. I really think it does have something to do with making Content-Type: application/x-www-form-urlencoded. 1.1 is much more strict that 1.

@mazdaknik would you mind posting more of your code? What do buildAuthorizationHeader() and buildBaseString look like? I’d love to know!


#16

cjsoftlab, The solution in the link that mitsuaki_i posted fixes the issue. Simply url encode your data for the post of the status or any other post data.


#17

Not for me. mitsuaki_i’s method (http://stackoverflow.com/questions/14672502/bug-or-spec-change-of-twitter-api-1-1) is applied when posting:

!
'
(
)
*

That’s not my case…unfortunately. Thanks anyway.


#18

FOUND A SOLUTION - using the Abraham TwitterOAuth library. If you are using an older implementation, the following lines should be added after the new TwitterOAuth object is instantiated:

$connection->host = "https://api.twitter.com/1.1/"; $connection->ssl_verifypeer = TRUE; $connection->content_type = 'application/x-www-form-urlencoded';

The first 2 lines are now documented in Abraham library Readme file, but the 3rd one is not. Also make sure that your oauth_version is still 1.0.


#19

Same issue here!!


#20

-All worked out- just add the lines above.