Twitter OAuth PHP Tutorial


Trying to get a dial tone with Twitter’s new OAuth can be a frustrating and daunting task.  Especially when it comes to the utter lack of proper documentation with regards to just connecting with to Twitter using OAuth.  This tutorial will walk you through the steps required to be able to make calls using Twitter’s OAuth in PHP.

Getting Started

OK, first things first.  You’ll need to have your web application registered with Twitter, as well as the associated username and password of the account.  If you haven’t registered your application with Twitter yet, here’s what you’ll need to do:

First visit

Click on the “Register an app” link.

Then fill out all the appropriate information requested.  Make sure that you’ve selected “Browser” as your “Application Type”.

You will also need to register a callback URL.  This is the URL where people will be redirected to after they have authorized your website/application for use with their Twitter account.  This is also where you will receive validation information directly from Twitter which will be required to make calls on behalf of the Twitter user.

Once you have filled out the form and registered your application, you’ll be presented with the details of your registration including your “Consumer Key” and “Consumer Secret”.  You’ll be using those shortly so keep a browser instance open or copy them down.

Twitter Application Registration

Twitter Application Registration

Now that the prerequisites are done, it’s time to being the battle with OAuth.

Beginning OAuth

First let’s understand what needs to happen to get OAuth working.

The gist is simple enough, we need to create a header with authorization data in it.  Post it to Twitter, get a token back from twitter letting us know we’re registered and everything is groovy.  Next we’ll retrieve the authorization URL to allow users to authorize our application with their account and finally, do something…Uh Twittery, Twitter-esc…I don’t know, don’t ask.

Now, the most important thing to remember here is Twitter is super picky about how everything is encoded…super picky.  So if you make one mistake, you’ll get a forbidden and get rejected with very little help response message wise from Twitter.

So let’s start by getting the request token from Twitter, which will let us know we’re on the right track.

Getting The Request Token

To get the request token from Twitter we need to POST a call to:

But first we need to sign and encode an authorization header, and is a pain.  Lucky for you I’ve already been through this so you don’t have to deal with figuring it all out.  Here we go.

The authorization header required for the request token requires the following fields:

  • oauth_callback – the url to be redirected to after authorization
  • oauth_consumer_key – this is the consumer key you get after registering your application with Twitter
  • oauth_nonce – this is a unique value that you generate to reduce the chance of someone hijacking your session
  • oauth_signature_method – this is the method used to sign the base string, we’ll get to this in a bit, but for now the default value is “HMAC-SHA1”
  • oauth_timestamp – this is the current timestamp.
  • oauth_version – this is going to be “1.0”

An easy way to deal with the authorization header and it’s nuances is to load all the oauth header values into an associative array and pass them to functions that will sign, encode, etc.

$nonce = time();
$timestamp = time();
$oauth = array('oauth_callback' => '',
              'oauth_consumer_key' => 'yourconsumerkey',
              'oauth_nonce' => $nonce,
              'oauth_signature_method' => 'HMAC-SHA1',
              'oauth_timestamp' => $timestamp,
              'oauth_version' => '1.0');

Just to clarify what I’ve done so far.  The $nonce variable can be pretty much whatever you want, I thought for the purpose of this tutorial however time() would be the easiest to understand.  The $timestamp, well that should be pretty obvious.  The $oauth is our associative array containing all the fields and values required to get us started.

Now that we have our oauth array, we need to create our base string.  The base string is basically a signature of the action we want to perform which later we will sign using HMAC-SHA1 and our composite key.  The result of which will be our oauth_signature.  I know it sounds a bit confusing, but don’t worry.  I’ll walk you through the entire process step by step.

So let’s build the base string.  The base string has the format of:


For example, here’s a fully encoded base string:


Yeah, it’s ugly.  And here’s how you create it.  As I said before Twitter is very picky about encoding, etc.  So to ensure everything is encoded the same way each and every time, let’s use a function that will do it for use using our $oauth array.

 * Method for creating a base string from an array and base URI.
 * @param string $baseURI the URI of the request to twitter
 * @param array $params the OAuth associative array
 * @return string the encoded base string
function buildBaseString($baseURI, $params){
$r = array(); //temporary array
    ksort($params); //sort params alphabetically by keys
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value); //create key=value strings
    }//end foreach                
    return 'POST&' . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r)); //return complete base string
}//end buildBaseString()

So here’s what the buildBaseString() function does.  It takes the $baseURI, in this case “” and the $oauth array we created and hands back the encoded base string.  It does this by first sorting the $oauth array according to keys (this is required by Twitter, one of the gotchas), then it creates a “key=value” string using rawurlencode (i.e. oauth_signature=HMAC-SHA1, rawurlencode is another gotcha), then it creates and hands back the base string after yet another full rawurlencode of all the “key=value” strings (this was a major gotcha, took me forever to figure out).  I can’t stress enough how absolutely imperative it is that the base string gets created exactly like this.  Any deviation for this can easily result in forbidden/unauthorized rejections from Twitter.

Now that we have a way to create a base string let’s create one.

$baseString = buildBaseString($baseURI, $oauth);

And wallah, a base string…yay!  Now we need to sign it.  To sign the base string we’ll need to do a couple of things.  The first is to create the composite key.  The composite key is the result of a rawurlencode of the consumer secret separated by the “&” followed by the rawurlencode of the token.  Now, being that we are trying to retrieve the token we don’t have that just yet and it’s set to null.  But for all calls after we get our request token, we’ll need to make sure it is included in the composite key otherwise the call will be rejected.  Once again to make live easy, let’s create a function called getCompositeKey().

 * Method for creating the composite key.
 * @param string $consumerSecret the consumer secret authorized by Twitter
 * @param string $requestToken the request token from Twitter
 * @return string the composite key.
function getCompositeKey($consumerSecret, $requestToken){
    return rawurlencode($consumerSecret) . '&' . rawurlencode($requestToken);
}//end getCompositeKey()

That function is pretty self explanatory.  Now to actually sign the base string we’ll need to use the composite key, sign it with the binary form of HMAC-SHA1 and encode the result as base64.  This will create our oauth_signature which we will need to finalize our request to Twitter.  This is what you’ll need.

$consumerSecret = 'consumer-secret'; //put your actual consumer secret here, it will look something like 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98'
$compositeKey = getCompositeKey($consumerSecret, null); //first request, no request token yet
$oauth_signature = base64_encode(hash_hmac('sha1', $baseString, $compositeKey, true); //sign the base string
$oauth['oauth_signature'] = $oauth_signature; //add the signature to our oauth array

First we create our composite key by passing in the consumer secret that you received when you registered your application with Twitter.  We pass in null for the $requestToken argument because that’s what we’re going to retrieve.  Next we sign our base string.  Then add the $oauth_signature to our $oauth array to be used in our authorization header.  Now, let’s build us a header buddy…yee haw!

The header once constructed will need to have the following format:

Authorization: OAuth key=value, key=value, …

Once again, to make life easy, why don’t we build a function to build Authorization header for us.

 * Method for building the OAuth header.
 * @param array $oauth the oauth array.
 * @return string the authorization header.
function buildAuthorizationHeader($oauth){
    $r = 'Authorization: OAuth '; //header prefix
    $values = array(); //temporary key=value array
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\""; //encode key=value string
    $r .= implode(', ', $values); //reassemble
    return $r; //return full authorization header
}//end buildAuthorizationHeader()

This function simply takes in the $oauth array and transforms it into the Authorization header format.  The only caveat here is that the values need to be wrapped in rawurlencode (yet another gotcha).  Now all that we really need to do is construct our header and place a call out to Twitter and get the request token back.  To make the request across the line to Twitter, I used cURL.  PHP makes it easy to use, so let’s wrap it in a function that we’ll use for all Twitter calls going forward.  Now there’s a bit of a gotcha here that’s undocumented (ofcourse).  When you build the header you will also need to pass in an “Expect: ” header option, otherwise Twitter will complain and fail.  Something like:

 * Method for sending a request to Twitter.
 * @param array $oauth the oauth array
 * @param string $baseURI the request URI
 * @return string the response from Twitter
function sendRequest($oauth, $baseURI){
    $header = array( buildAuthorizationHeader($oauth), 'Expect:'); //create header array and add 'Expect:'
    $options = array(CURLOPT_HTTPHEADER => $header, //use our authorization and expect header
                           CURLOPT_HEADER => false, //don't retrieve the header back from Twitter
                           CURLOPT_URL => $baseURI, //the URI we're sending the request to
                           CURLOPT_POST => true, //this is going to be a POST - required
                           CURLOPT_RETURNTRANSFER => true, //return content as a string, don't echo out directly
                           CURLOPT_SSL_VERIFYPEER => false); //don't verify SSL certificate, just do it
    $ch = curl_init(); //get a channel
    curl_setopt_array($ch, $options); //set options
    $response = curl_exec($ch); //make the call
    curl_close($ch); //hang up
    return $response;
}//end sendRequest()

Please  note: You may need to add CURLOPT_POSTFIELDS => ” depending on the version of PHP you are using. ~thanks to Thomas Krantz

So this function sends a request to Twitter (obviously), it constructs the header using the buildAuthorizationHeader() function and adds the ‘Expect:’ directive as is required to communicate with Twitter successfully.  We set the cURL options, make the call, hang up and return the result.  Now let’s put that into action.

$baseString = buildBaseString($baseURI, $oauth); //build the base string
$compositeKey = getCompositeKey($consumerSecret, null); //first request, no request token yet
$oauth_signature = base64_encode(hash_hmac('sha1', $baseString, $compositeKey, true)); //sign the base string
$oauth['oauth_signature'] = $oauth_signature; //add the signature to our oauth array
$response = sendRequest($oauth, $baseURI); //make the call

Now, if all went well your response should contain the “oauth_token” and the “oauth_token_secret”.  If not, you must have typed something wrong, keep trying until you get the token and secret handed back, or drop me a line and I’ll make sure I didn’t mistype something.

Now, take the “oauth_token” and the “oauth_token_secret” and store it.  We’re going to be using it to make a call to get our authorization url.

Constructing The Authorization URL

To construct the authorization URL, we’re going to be using the request token we received back from Twitter in the previous section Getting The Request Token, the “oauth_token”.  The authorization url has the following format:$oauth_token

Where the $oauth_token variable is the actual value your received from Twitter parameterized as “oauth_token”.  Redirect the browser to this URL and it will prompt the user for their Twitter username/password if they’re not logged in, then it will ask permission to authorize use with your registered application.  You should see something similar to the following:

Twitter Connect Authorization

Once the user has authorized use, the browser will be redirect back to the “oauth_callback” parameter you specified earlier in your get request token call.  Here is where you will receive the user’s “screen_name”, “user_id”, “oauth_token” and “oauth_token_secret”.  Store these values and use them to make calls on behalf of the user to Twitter.  Hopefully this has helped you get over the initial shell shock and Twitter OAuth hurdle.  From this point forward, you’ll want to reference to find out more on making calls to Twitter resources on behalf of the user.

The source code for this example is available for download and use:

Download Project Files

82 thoughts on “Twitter OAuth PHP Tutorial

  1. Kristian Nielsen

    Hey there,

    Really appreciate the tutorial! However, I keep getting this when executing:

    {“errors”:[{“code”:32,”message”:”Could not authenticate you.”}]}

    Any idea why this is?

    Your help will be appreciated!

    1. godlikemouse Post author

      Hi Kristian,

      My guess here would be that the signature is correct. Of course without details or code it’s truly just a guess. You may also want to just use one of the pre-built libraries now available, they’re pretty good now days.

      1. Kristian Nielsen

        Thank you for the quick response – appreciated.

        I know they’re libraries, but I prefer this kind of code, since it makes much more sense to me 🙂

        Did you try out the script recently? Just curious if Twitter changed something from their side, so it’s not fully compatible anymore or so?

        I’ll play around a bit to see if I can get it to work, but if you have a chance to try out the script from your end, that would be highly appreciated as well 🙂

        Enjoy your day!

        1. godlikemouse Post author

          Hi Kristian,

          Sorry, I haven’t tried this script in years. This was originally developed quite a while back when the libraries we were trying to use just wouldn’t work. Best of luck.

  2. Rahul Dhamecha

    @GodLikeMouse : Great post I was searching for this. I have googling but everybody telling on web to use a PHP library to make an Authentication to twitter. You have explained it well here. Glad to find such a good post.

  3. Bhagwat Chouhan

    Thanks a lot for sharing this post with details required for each and every step. It helped me to resolve all the twitter oauth issues I was facing since last few days.

  4. Qarni

    Thank you very much .. Your code’s been of a great help.
    I am a bit new to the whole Twitter API and I could agree with you more about their documentation being crap!!

    I am getting to the point where the authentication page redirects me to the callback page. In the url I see oauth_token, and oauth_verifier but nothing else while from the last paragraph of your tutorial, I got the idea that I’d need screen-name, user_id, and oauth_token_secret but I don’t know how!!

    1. godlikemouse Post author

      Hi Qarni,

      What are you seeing in the body of the response? If you could include the url, headers and response body that would be helpful.

  5. jasdak

    Thank you so much Jason. I used your code and modified it slightly to work with the Ravelry OAuth API. Wanted to share the code that I got working successfully. I added some code to your file to handle automatically sending a CURL request for the access token after we get back the approved authorization.

    Code located here:

  6. srinivas

    Hi thanks for your post. it clarifies the twitter reverse authentication problems. So basically I am trying to get reverse auth working. I can verified on the twitter site that it works with the sample curl command they generate, but when I am using your code it fails “Failed to validate oauth signature and token”

    I have added the x_auth_mode = reverse_auth and plus the CURLOPT_POSTFIELDS also, but still not working.

    1. godlikemouse Post author

      Hi srinivas,

      It sounds like there is something wrong with the way you are signing the content. I’m not sure exactly where with the limited details you’ve provided but you may want to start there.

      1. srinivas

        Here I am printing the return header, and I am getting 401 Authorization Required. Also its strange that the error says Failed to validate oauth signature and token, when in fact there is no token being passed.

        string 'POST&' (length=254)
        array (size=2)
          0 => string 'Authorization: OAuth, Content-Type: application/x-www-form-urlencoded, content-length: 0,oauth_consumer_key="88x88QmTY1fOCcugjm0QVVJpw", oauth_nonce="1406039935", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1406039935", oauth_version="1.0", x_auth_mode="reverse_auth", oauth_signature="GZWULKml9hJ81gkl5XIBv%2Ffn2tM%3D"' (length=328)
          1 => string 'Expect:' (length=7)

        “HTTP\/1.1 401 Authorization Required\r\ncache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0\r\ncontent-length: 44\r\ncontent-security-policy-report-only: default-src https:; connect-src https:; font-src https: data:; frame-src https: http:\/\/* http:\/\/ about: javascript:; img-src https: data:; media-src https:; object-src https:; script-src \u0027unsafe-inline\u0027 \u0027unsafe-eval\u0027 about: https:; style-src \u0027unsafe-inline\u0027 https:; report-uri https:\/\/\/i\/csp_report;\r\ncontent-type: text\/html; charset=utf-8\r\nexpires: Tue, 31 Mar 1981 05:00:00 GMT\r\nlast-modified: Tue, 22 Jul 2014 14:39:01 GMT\r\npragma: no-cache\r\nserver: tsa_d\r\nset-cookie: _twitter_sess=BAh7CCIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7ADoHaWQiJTRhNDhjMjUwZGY5N2ViZTU0M2FiNjI0%250ANjE0YTQxNjBiOg9jcmVhdGVkX2F0bCsIEuOCXkcB–1a96c2cf1c3dec8fe7c06bb7105ddac80a247768;; path=\/; secure; HttpOnly\r\nset-cookie: guest_id=v1%3A140603994177289778;; Path=\/; Expires=Thu, 21-Jul-2016 14:39:01 UTC\r\nstatus: 401 Unauthorized\r\nstrict-transport-security: max-age=631138519\r\nvary: Accept-Encoding\r\nx-content-type-options: nosniff\r\nx-frame-options: SAMEORIGIN\r\nx-mid: d9291b692a116adc52808f17fd6632336775fb88\r\nx-runtime: 0.00864\r\nx-transaction: 0dc17dbe1ee97f1f\r\nx-ua-compatible: IE=edge,chrome=1\r\nx-xss-protection: 1; mode=block\r\ndate: Tue, 22 Jul 2014 14:39:42 UTC\r\nx-connection-hash: 9f09b78f9943db01c0a55205ca173350\r\n\r\nFailed to validate oauth signature and token”

        1. godlikemouse Post author

          I believe you still need to include the token even if it doesn’t exist yet or at least the place holder for it. If you have a look at the getCompositeKey function and the next step which encodes the oauth_signature it may give you some insight as to what the actual issue is. There are no optional steps in the operations listed above, they must all be followed to the letter including the sorting of the parameters. Hope this helps.

          1. srinivas

            Thanks for looking into it. I got the reverse auth working by extending j7mbo lib. Here is the link for anyone interested:

            I also tried the same this with your code, adding the token, but it was still giving error. Its in the way the signature is being generated, specially for x_auth_mode where the composite key is being generated.

            In many place I saw that people are passing null, but this does not work for x_auth_mode, instead one should use:
            $composite_key = rawurlencode($consumer_secret) . ‘&’ . rawurlencode(”);

  7. alex

    dude ur amazing u saved my ass. i was trying to make it work for like hours. and u had everything done neat and clean. awesome code

  8. Olivier Leduc

    Thanks, this was useful even after three years.

    Alright, so there are a few issues with this tutorial, first of all, buildAuthorizationHeader() is throwing an error in php 5.4, the quotes are messed up, here is the fixed line:
    $values[] = $key.’=”‘ . rawurlencode($value) . ‘”‘;

    Second, in buildBaseString() you forgot a closing parenthesis, here is the fixed line:
    return $method.”&” . rawurlencode($baseURI) . ‘&’ . rawurlencode(implode(‘&’, $r));

    And the third and most frustrating issue, is for people who get a 400 error code with an empty string has a response, you need to add “content-length: 0” in your header array.

    Thank a lot for the great post!

    1. Olivier Leduc

      Actually no it was this line who lacked a closing parenthesis:
      $oauth_signature = base64_encode(hash_hmac(‘sha1’, $baseString, $compositeKey, true); //sign the base string

      It should be:
      $oauth_signature = base64_encode(hash_hmac(‘sha1’, $baseString, $compositeKey, true)); //sign the base string

      1. godlikemouse Post author

        Thank you for the corrections, I’ll make sure the changes get added to the post.

  9. andy

    the bl***y Twitter documentation is driving me crazy – it seems to contradict itself from page to page. But, in the above code you suggest that to obtain the request token one needs to include various parameters including signature method but you omit the actual signature from the listed required parameters. The api documentation suggests that this is required…. but in the twitter docs the order of parameters in auth header is peculiar – it is not, by the looks of things – ordered in the same alphabetical manner
    ( )

    1. godlikemouse Post author

      Hi Andy, the Twitter docs are complete crap for the most part unfortunately. You may want to try one of the supported API libraries available, they aren’t quite as bad as when I first wrote this article. Also, the signature referred to is the oauth_signature, it’s an sha1 hash of the $baseString and the $compositeKey:

      $oauth_signature = base64_encode(hash_hmac(‘sha1’, $baseString, $compositeKey, true); //sign the base string

      It gets added into the array before the sendRequest call like so:

      $oauth[‘oauth_signature’] = $oauth_signature; //add the signature to our oauth array

      Then you make the sendRequest call:

      $response = sendRequest($oauth, $baseURI); //make the call

  10. marr

    Great code! I am not receiving user_id; is Twitter still sending? Also, how would I get user email?

    Thanks again.

    1. godlikemouse Post author

      Hi Marr,

      I believe what you’re looking for is available by use of the “me” call in the api. Check out the Twitter docs at and look into the user api. That should give you what you need.

  11. marr

    Great script! Everything works except user_id and screen_name are not being returned. Has Twitter stopped returning them? I’m looking for user email, any idea on how to get that??


    1. godlikemouse Post author

      Glad to help. I know, what an awesome comment. Hopefully she was hot (because she was in my head) 🙂

  12. GodLikeMouse Post author

    Hi Marina, sounds like there might be a problem with the redirect uri or the callback url. What do you have your callback set to in your PHP and the redirect set to under the Twitter settings?

  13. Marina

    Fixed the previous but the problem now is that after it takes me to the twitter page: Authorize My new api Application to use your account?

    and I hit Authorize App, it redirects me back to the same previous step.(“Authorize My new api Application to use your account?”.

    Any idea what it might be?

  14. Marina

    wanted to say thank you for all the help and guidance you offer here.

    I’m doing a project for school and want to be able to tweet the text om a site’s feed to it’s twitter account.

    I’m trying to see if the Twitter_OAuth works to start with but when trying to direct the browser to$oauth_token

    it gives me this result:

    “Whoa there!

    There is no request token for this page. That’s the special key we need from applications asking to use your Twitter account. Please go back to the site or application that sent you here and try again; it was probably just a mistake.”

    Can you tell me what this means and how I fix it?
    Thank you!

  15. GodLikeMouse Post author

    Hi Mujibur, make sure that your date/time is correct on the machine running the code. If the date skew is off by too much, the oauth will fail on Twitter’s side. I would recommend using ntpdate or something similar.

  16. Mujibur

    I have used the code you provided.
    It was working fine for me but last 15 days its not working at all.
    Also it is not creating the oauth_token.
    Can you please take a look if you get time.

    Thanks in advance.


  17. Alex

    I keep on getting this message:
    Whoa there!
    There is no request token for this page. That’s the special key we need from applications asking to use your Twitter account. Please go back to the site or application that sent you here and try again; it was probably just a mistake.

    Anyone knows whats wrong?
    When I create the post signature, what should I put in Request URI?

    1. GodLikeMouse Post author

      I’ve seen this happen on a few different occasions. The first and most obvious is usually that either the key or the secret is wrong. The second and less obvious is the date skew. Make sure your time on the box is correct by using NTP or something similar. Other than that, it might be programmatic in nature.

  18. sandeep

    Hello Ben and ginger, update following part from the posted code, it may resolve ur problem.

    $options = array(CURLOPT_HTTPHEADER => $header,
    CURLOPT_HEADER => false,
    CURLOPT_URL => $baseURI,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => “”, // this is the change

  19. Ginger

    That’s the error i get and i didn’t change anything just the stuff for my consumer and my callback

    Request Entity Too Large

    The requested resource
    does not allow request data with POST requests, or the amount of data provided in the request exceeds the capacity limit.

  20. GodLikeMouse Post author

    Hi Ben, make sure your server or development box time is correct. Use NTP or something to sync and verify. I’ve seen Twitter complain when the time is too far skewed. The only other thing I can think of is possibly a difference in PHP/Curl versions. You might want to try doing an update on curl first and see if that helps.

  21. Ben

    Excellent tutorial,
    I download the project file, unpackaged it, replaced the oauth_callback, oauth_consumer_key and consumerSecret variables, but when I load the page Twitter is responding with:

    Whoa there!
    There is no request token for this page. That’s the special key we need from applications asking to use your Twitter account. Please go back to the site or application that sent you here and try again; it was probably just a mistake.

    So I did a var_dump() on the $response variable, and this is part of the response:
    413 Request Entity Too Large

    Request Entity Too Large
    The requested resource/oauth/request_token
    does not allow request data with POST requests, or the amount of data provided in
    the request exceeds the capacity limit.

    Any ideas?
    Thanks in advance!

  22. GodLikeMouse Post author

    You can modify the sendRequest method to take an additional parameter with a default value, something like $post = true and then set the CURLOPT_POST => $post. That way you can call it passing in a false and it will make a GET request.

  23. l0garithm

    AH! sorry for the spamming but my first part of the code is getting censored out:
    // here i include the mylib.php file which contains all those functions you wrote and i use here a couple of times
    $nonce = time();
    $timestamp = time();

    $oauth = array(‘oauth_consumer_key’ => $consumerKey, //from here it’s in my first post
    ‘oauth_nonce’ => $nonce,
    ‘oauth_signature_method’ => ‘HMAC-SHA1’,
    ‘oauth_token’ => $_GET[‘oauth_token’],
    ‘oauth_timestamp’ => $timestamp,
    ‘oauth_verifier’ => $_GET[‘oauth_verifier’],
    ‘oauth_version’ => ‘1.0’);

    If this gets censored out too, the code is similar to the one used to create the oauth2 array,but here the variable is oauth.
    Again,sorry for the spamming.

  24. l0garithm

    sorry for the incomplete file this comes on the top of the file
    $consumerKey, // from here it’s in my first post
    ‘oauth_nonce’ => $nonce,
    ‘oauth_signature_method’ => ‘HMAC-SHA1’,
    ‘oauth_token’ => $_GET[‘oauth_token’],
    ‘oauth_timestamp’ => $timestamp,
    ‘oauth_verifier’ => $_GET[‘oauth_verifier’],
    ‘oauth_version’ => ‘1.0’);
    $accesTokenURI = ‘’;
    $baseStringAccess = buildBaseString($accesTokenURI, $oauth);

  25. l0garithm

    It dosnt have to be simplexml,dom is fine as well,but the problem i encounter is at retriving that xml file from twitter.
    I’ve followed the described steps and created the following callback.php (where mylib.php contains all the functions you have created, and also stores $consumerKey and $consumerSecret):
    ‘oauth_nonce’ => $nonce,
    ‘oauth_signature_method’ => ‘HMAC-SHA1’,
    ‘oauth_token’ => $_GET[‘oauth_token’],
    ‘oauth_timestamp’ => $timestamp,
    ‘oauth_verifier’ => $_GET[‘oauth_verifier’],
    ‘oauth_version’ => ‘1.0’);
    $accesTokenURI = ‘’;
    $baseStringAccess = buildBaseString($accesTokenURI, $oauth);

    $compositeKey = getCompositeKey($consumerSecret, $_GET[‘oauth_token’]);
    $oauth_signature = base64_encode(hash_hmac(‘sha1’, $baseStringAccess, $compositeKey, true)); //sign the base string
    $oauth[‘oauth_signature’] = $oauth_signature;
    $response = sendRequest($oauth, $accesTokenURI); //getting the access tokens – up to this point it works great
    $responseArray = array();
    $parts = explode(‘&’, $response);
    foreach($parts as $p){
    $p = explode(‘=’, $p);
    $responseArray[$p[0]] = $p[1];
    //echo $response;
    //echo var_dump($responseArray);

    //thise 3 variables are retrieved from the request -up to this points it works
    $oauth_access_token = $responseArray[‘oauth_token’];
    $oauth_access_token_secret = $responseArray[‘oauth_token_secret’];
    $username = $responseArray[‘screen_name’];
    echo “Hello $username!”;

    $nonce2 = rand(-123123, 2323423534);
    $timestamp2 = time();
    $oauth2 = array(‘oauth_consumer_key’ => $consumerKey,
    ‘oauth_nonce’ => $nonce2,
    ‘oauth_signature_method’ => ‘HMAC-SHA1’,
    ‘oauth_token’ => $oauth_access_token,
    ‘oauth_timestamp’ => $timestamp2,
    ‘oauth_version’ => ‘1.0’);

    $userInfoURI = ‘’;

    $baseStringInfo = buildBaseString($userInfoURI, $oauth2);
    //echo $baseStringInfo;

    $compositeKey2 = getCompositeKey($consumerSecret, $oauth_access_token_secret);
    $oauth_signature2 = base64_encode(hash_hmac(‘sha1’, $baseStringInfo, $compositeKey2, true)); //sign the base string
    $oauth2[‘oauth_signature’] = $oauth_signature2;
    $response2 = sendRequest($oauth2, $userInfoURI);// here i should get my xml file
    echo var_dump($response2);// prints some error message ->here is the problem
    // it says something like this:This method requires a GET.


    //end class
    I’m guessing the problem comes from the curlopt things in the sendrequest function (needs get instead of post or something) but i dont know how to manage it.
    So i manage to get “screen_name”, “user_id”, “oauth_token” and “oauth_token_secret” but i dont know how to use them to retrieve data about the user or write tweets on his behalf.
    If you could try my code, make it work and tell me what i’m doing wrong i’ll be forever grateful.

  26. GodLikeMouse Post author

    Does it have to be simplexml? I use DOM, it’s a lot more straight forward and easy to use. Using DOM to do what you’re asking you would simple do this:

    //make call to twitter and retrieve xml as $xml…
    $doc = new DOMDocument(); //new doc
    $doc->loadXML($xml); //load xml
    $doc->getElementsByTagName(‘…’); //get elements

    With simplexml you’d have to do something like this:

    //make call to twitter and retrieve xml as $xml…
    $element = new SimpleXMLElement($xml); //load xml
    $element->hash->request; //get request element

    With simplexml you’ll need to know the actual path, my example was just for show, you’ll need to replace the hash->request with actual child node names.

  27. l0garithm

    but what should i write in my callback.php page? How should i use this query string to obtain a variable – so i can play with it using simplexml.With the library i was using the built in function to get this xml: $content1 = $someobjectinstance->OAuthRequest (‘’,’GET’, array());
    $user = simplexml_load_string($content1);…//more process code here
    thanks for the reply

  28. GodLikeMouse Post author

    I’m not sure about Tumblr. The implementation above is specifically for Twitter’s OAuth. There very well might be some slight/huge differences in how Tumblr is implementing their OAuth. I would look through the OAuth examples in the Tumblr API documentation to see what they expect.

  29. Mick

    I have this working with twitter just as your example does but when i try to use it with tumblr i get an “oauth_signature does not match expected value” error. I can get the initial request_token and authorize but when i go to pull the access_token i get that error.

    For this line:
    $compositeKey = getCompositeKey($consumerSecret, null);

    I change it to:
    $compositeKey = getCompositeKey($consumerSecret, $oauth_token);

    Is that incorrect? Any ideas? thanks a zillion, mick

  30. Finn Wölm

    Oh 🙂 It works now. I am not sure what changed, but suddenly it started working 🙂 Thanks again 🙂

  31. Finn Wölm

    Hey 🙂 I changed the values for consumer-key, consumer-secret and callback URL. When I run the code I get an error when requesting the request_token: “Desktop applications only support the oauth_callback value ‘oob’ /oauth/request_token “.

    I tried making the change that was suggested(adding CURLOPT_POSTFIELDS => ” to the bottom of my CURLOPTS list. Now I get the error: ” Invalid Unicode value in one or more parameters /oauth/request_token “.

    Any ideas? 🙂 Thanks ahead <3

    Other than that I do not get the code to run, I really like this tutorial/guide. Great job! 🙂

  32. Girl Developer

    I love you. I want to have all your babies. IT WORKED FOR ME!!!!!!!!!! Finally, after DAYS of searching and HOURS of failed attempts…. *bow* Thank you, sir. Will contact you later for baby making.

  33. James

    Thank you for that Thomas! That was my problem as well. Awesome tutorial and thanks for including the full code example.

  34. Thomas Krantz


    Thanx for a very nice tutorial!

    Ran into a problem though. Depending on your version of PHP, curl might not send anything since you’re using POST and haven’t set CURLOPT_POSTFIELDS.

    The solution is obviously to add CURLOPT_POSTFIELDS => ” to the optionsarray. Just thought I’d mention it if anyone else have the same problem.

  35. cminor9

    thank you! oAuth has made me want to tear my eyes out and feed them to birds, and the kills the birds and destroy the entire earth with blazing anger of wrathful flames of fury! I don’t have the option of using PHP’s OAuth module, and I don’t want to use some nasty bloated 1000 lines of code someone else wrote without understanding what is actually happening. I have looked at documentation from several oAuth providers and just could not get the signing of requests quite right. This tutorial helped me get past that hurdle. Thanks and good work. I can now resume my happy existence.

  36. GodLikeMouse Post author

    Terribly sorry about that guys. I’ve fixed the issue in the download project files. Please let me know if you have any more problems or need help.

  37. Guilherme

    Hey man.
    There’s a parenthesis missing here:

    $oauth_signature = base64_encode(hash_hmac(‘sha1’, $baseString, $compositeKey, true)

    $oauth_signature = base64_encode(hash_hmac(‘sha1’, $baseString, $compositeKey, true))

    It not worked here.
    Anyways, nice post. If you have an idea of what can be going on, pls tell us.

Comments are closed.