Twitpic OAuth - I'm Stuck

by @edent | # # # # # # | 14 comments | Read ~3,235 times.

Twitpic has implemented an OAuth API. No more having to hand out passwords to all and sundy. Only I'm too much of a dunderhead to get it working. Perhaps it's a combination of heatstroke or this rotten head-cold, but I just can't see what I'm doing wrong. Any help much appreciated.

The easy bit.

It's easy to post the data to Twitpic

$media_data = array(
	'media' => '@'.$_FILES['media']['tmp_name'],
	'message' => html_entity_decode($_POST['message']),
	'key'=>'123465789132465'
);
curl_setopt($ch,CURLOPT_POSTFIELDS,$media_data);

OAuth Credentials

Using Abrahams OAuth library for PHP, it's easy to get the required OAuth data.

require_once('OAuth.php');
// instantiating OAuth customer
$consumer = new OAuthConsumer(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET);
// instantiating signer
$sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
// user's token
list($oauth_token, $oauth_token_secret) = explode('|', $GLOBALS['user']['password']);
$token = new OAuthConsumer($oauth_token, $oauth_token_secret);

// signing URL
$fakeurl = 'https://twitter.com/account/verify_credentials.xml';
$request = OAuthRequest::from_consumer_and_token($consumer, $token, 'GET', $fakeurl, array());
$request->sign_request($sha1_method, $consumer, $token);
$OAuthurl = $request->to_url();

The Tricky Bit

I'm following the header example in the API documentation. Passing these variable to Twitpic is where I seem to go wrong.

$header = array(
      'X-Auth-Service-Provider: https://api.twitter.com/1/account/verify_credentials.json',
      'X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/"'
   );

I then modify the second header so it reads

"X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/",
oauth_consumer_key="aaaaaaa",
oauth_nonce="bbbbbbbbbbb",
oauth_signature="ccccccccccccc%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="123456798",
oauth_token="15948715-dddddddddd",
oauth_version="1.0""

The Error

401 "Could not authenticate you (header rejected by twitter)."

GAH!

14 thoughts on “Twitpic OAuth - I'm Stuck

  1. Tom Parker says:

    Hmm. The only immediately obvious item (yet probably unlikely as I think/hope PHP would whinge about this) is that your replacement headers have a quote inside them around the api.twitter.com bit which hasn't been escaped like the original one was. Also, according to their example, they *all* need to have their parameters in quotes.

    The error you're getting is probably better translated to "our parser barfed, so let's assume you didn't give us *everything* we wanted and ergo panic". This is an insanely annoying and common problem when trying to build this sort of thing, and unfortunately there's a trade-off between nice error messages v.s. making it easier to find the flaws in stuff for dark-hat folks, and they tend to err on the paranoid side.

    (Also, twitpic is being a bit odd with OAuth, as the spec recommends the use of HTTP POST variables for sending all this stuff...)

    1. Ah! Indeed you are wise.
      The correct code should be
      $header = array('X-Auth-Service-Provider: https://api.twitter.com/1/account/verify_credentials.json',
      'X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/"');

      Now at least the error I get back is from Twitter!

    2. rik says:

      I'd be thinking the POST thing.

      1. Nah, the post works. If it didn't, Twitpic wouldn't forward the headers on to Twitter.

    3. I've updated the blogpost. Sending through the headers in what I think is the correct format. Now I get 401 “Could not authenticate you (header rejected by twitter).”

  2. Hi Terence,

    I believe the problem is that you are signing the OAuth request using verify_credentials.xml ($fakeurl = 'https://twitter.com/account/verify_credentials.xml). We need the request to be signed for https://api.twitter.com/1/account/verify_credentials.json. Try changing the value of $fakeurl and it should work.

    1. You beauty! Nice one. Can't believe I missed that.

      All seems to work - the image appears on Twitpic, but not on Twitter. Is there a specific parameter I need to pass?

      Thanks

      T

      1. Hi Terence,

        Unfortunately, with the way OAuth Echo works, we can only access the URL that you sign for (in this case, https://api.twitter.com/1/account/verify_credentials.json). This means, that we are unable to post a tweet on your behalf to twitter, because the oauth header you are signing is not for statuses/update.

        Twitter is working on a solution for us, but, for the time being, you'll have to post the tweet yourself. When you upload an image, the twitpic url is included in the JSON or XML response, so you can pull the URL from there to insert into your tweet.

        1. Perfect. Got it working. Thanks for all your help.

  3. Forget my comment. Got it workin' too. Thank you anyway.

  4. toshi says:

    At last, Did you work well? if so, tell me more specific?
    i got 401 “Could not authenticate you (header rejected by twitter).” now.

    could you paste some code on this board?

  5. toshi says:

    thank you very much!
    my mistake is OAuth libraries, that is kind of wrong.
    $schema was always designated 'http'. in function get_normalized_http_url().
    changing it to Abraham’s OAuth libraries, getting things down!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.