Sample code for 30+ languages & platforms
PHP ActiveX

Twitter OAuth1 Authorization (3-legged)

See more OAuth1 Examples

Demonstrates 3-legged OAuth1 authorization for Twitter.

This example is deprecated and no longer valid.

Chilkat PHP ActiveX Downloads

PHP ActiveX
<?php

$success = 0;

$consumerKey = 'TWITTER_CONSUMER_KEY';
$consumerSecret = 'TWITTER_CONSUMER_SECRET';

$requestTokenUrl = 'https://api.twitter.com/oauth/request_token';
$authorizeUrl = 'https://api.twitter.com/oauth/authorize';
$accessTokenUrl = 'https://api.twitter.com/oauth/access_token';

// The port number is picked at random. It's some unused port that won't likely conflict with anything else..
$callbackUrl = 'http://localhost:3017/';
$callbackLocalPort = 3017;

// The 1st step in 3-legged OAuth1.0a is to send a POST to the request token URL to obtain an OAuth Request Token
$http = new COM("Chilkat.Http");

$http->OAuth1 = 1;
$http->OAuthConsumerKey = $consumerKey;
$http->OAuthConsumerSecret = $consumerSecret;

$req = new COM("Chilkat.HttpRequest");
$req->AddParam('oauth_callback',$callbackUrl);

$req->HttpVerb = 'POST';
$req->ContentType = 'application/x-www-form-urlencoded';

$resp = new COM("Chilkat.HttpResponse");
$success = $http->HttpReq($requestTokenUrl,$req,$resp);
if ($success == 0) {
    print $http->LastErrorText . "\n";
    exit;
}

// If successful, the resp.BodyStr contains something like this:  
// oauth_token=-Wa_KwAAAAAAxfEPAAABV8Qar4Q&oauth_token_secret=OfHY4tZBX2HK4f7yIw76WYdvnl99MVGB&oauth_callback_confirmed=true
print $resp->BodyStr . "\n";

if ($resp->StatusCode != 200) {
    print 'Failed response status code: ' . $resp->StatusCode . "\n";
    exit;
}

$hashTab = new COM("Chilkat.Hashtable");
$hashTab->AddQueryParams($resp->BodyStr);

$requestToken = $hashTab->lookupStr('oauth_token');
$requestTokenSecret = $hashTab->lookupStr('oauth_token_secret');
$http->OAuthTokenSecret = $requestTokenSecret;

print 'oauth_token = ' . $requestToken . "\n";
print 'oauth_token_secret = ' . $requestTokenSecret . "\n";

// ---------------------------------------------------------------------------
// The next step is to form a URL to send to the authorizeUrl
// This is an HTTP GET that we load into a popup browser.
$sbUrlForBrowser = new COM("Chilkat.StringBuilder");
$sbUrlForBrowser->Append($authorizeUrl);
$sbUrlForBrowser->Append('?oauth_token=');
$sbUrlForBrowser->Append($requestToken);
$url = $sbUrlForBrowser->getAsString();

// Launch the system's default browser navigated to the URL.
$oauth2 = new COM("Chilkat.OAuth2");
$success = $oauth2->LaunchBrowser($url);
if ($success == 0) {
    print $oauth2->LastErrorText . "\n";
    exit;
}

// When the url is loaded into a browser, the response from Twitter will redirect back to localhost:3017
// We'll need to start a socket that is listening on port 3017 for the callback from the browser.
$listenSock = new COM("Chilkat.Socket");

$backLog = 5;
$success = $listenSock->BindAndListen($callbackLocalPort,$backLog);
if ($success == 0) {
    print $listenSock->LastErrorText . "\n";
    exit;
}

// Wait for the browser's connection in a background thread.
// (We'll send load the URL into the browser following this..)
// Wait a max of 60 seconds before giving up.
$sock = new COM("Chilkat.Socket");
$maxWaitMs = 60000;
// task is a Chilkat.Task
$task = $listenSock->AcceptNextAsync($maxWaitMs,$sock);
$task->Run();

// Wait for the listenSock's task to complete.
$success = $task->Wait($maxWaitMs);
if (!$success or ($task->StatusInt != 7) or ($task->TaskSuccess != 1)) {
    if (!$success) {
        // The task.LastErrorText applies to the Wait method call.
        print $task->LastErrorText . "\n";
    }
    else {
        // The ResultErrorText applies to the underlying task method call (i.e. the AcceptNextConnection)
        print $task->Status . "\n";
        print $task->ResultErrorText . "\n";
    }

    exit;
}

// If we get to this point, the connection from the browser arrived and was accepted.

// We no longer need the listen socket...
// Stop listening on port 3017.
$listenSock->Close(10);

// Read the start line of the request..
$startLine = $sock->receiveUntilMatch('\r\n');
if ($sock->LastMethodSuccess == 0) {
    print $sock->LastErrorText . "\n";
    exit;
}

// Read the request header.
$requestHeader = $sock->receiveUntilMatch('\r\n\r\n');
if ($sock->LastMethodSuccess == 0) {
    print $sock->LastErrorText . "\n";
    exit;
}

// The browser SHOULD be sending us a GET request, and therefore there is no body to the request.
// Once the request header is received, we have all of it.
// We can now send our HTTP response.
$sbResponseHtml = new COM("Chilkat.StringBuilder");
$sbResponseHtml->Append('<html><body><p>Chilkat thanks you!</b></body</html>');

$sbResponse = new COM("Chilkat.StringBuilder");
$sbResponse->Append('HTTP/1.1 200 OK\r\n');
$sbResponse->Append('Content-Length: ');
$sbResponse->AppendInt($sbResponseHtml->Length);
$sbResponse->Append('\r\n');
$sbResponse->Append('Content-Type: text/html\r\n');
$sbResponse->Append('\r\n');
$sbResponse->AppendSb($sbResponseHtml);

$sock->SendString($sbResponse->getAsString());
$sock->Close(50);

// The information we need is in the startLine.
// For example, the startLine will look like this:
//  GET /?oauth_token=abcdRQAAZZAAxfBBAAABVabcd_k&oauth_verifier=9rdOq5abcdCe6cn8M3jabcdj3Eabcd HTTP/1.1
$sbStartLine = new COM("Chilkat.StringBuilder");
$sbStartLine->Append($startLine);
$numReplacements = $sbStartLine->Replace('GET /?','');
$numReplacements = $sbStartLine->Replace(' HTTP/1.1','');
$sbStartLine->Trim();

// oauth_token=abcdRQAAZZAAxfBBAAABVabcd_k&oauth_verifier=9rdOq5abcdCe6cn8M3jabcdj3Eabcd
print 'startline: ' . $sbStartLine->getAsString() . "\n";

$hashTab->Clear();
$hashTab->AddQueryParams($sbStartLine->getAsString());

$requestToken = $hashTab->lookupStr('oauth_token');
$authVerifier = $hashTab->lookupStr('oauth_verifier');

// ------------------------------------------------------------------------------
// Finally , we must exchange the OAuth Request Token for an OAuth Access Token.

$http->OAuthToken = $requestToken;
$http->OAuthVerifier = $authVerifier;

// We don't need the "Authorization: OAuth ..." header for this POST.
$http->OAuth1 = 0;
$req->RemoveParam('oauth_callback');
$req->AddParam('oauth_verifier',$authVerifier);
$req->AddParam('oauth_token',$requestToken);

$req->HttpVerb = 'POST';
$req->ContentType = 'application/x-www-form-urlencoded';

$success = $http->HttpReq($accessTokenUrl,$req,$resp);
if ($success == 0) {
    print $http->LastErrorText . "\n";
    exit;
}

// Make sure a successful response was received.
if ($resp->StatusCode != 200) {
    print $resp->StatusLine . "\n";
    print $resp->Header . "\n";
    print $resp->BodyStr . "\n";
    exit;
}

// If successful, the resp.BodyStr contains something like this:
// oauth_token=85123455-fF41296Bi3daM8eCo9Y5vZabcdxXpRv864plYPOjr&oauth_token_secret=afiYJOgabcdSfGae7BDvJVVTwys8fUGpra5guZxbmFBZo&user_id=85612355&screen_name=chilkatsoft&x_auth_expires=0
print $resp->BodyStr . "\n";

$hashTab->Clear();
$hashTab->AddQueryParams($resp->BodyStr);

$accessToken = $hashTab->lookupStr('oauth_token');
$accessTokenSecret = $hashTab->lookupStr('oauth_token_secret');
$userId = $hashTab->lookupStr('user_id');
$screenName = $hashTab->lookupStr('screen_name');

// The access token + secret is what should be saved and used for
// subsequent REST API calls.
print 'Access Token = ' . $accessToken . "\n";
print 'Access Token Secret = ' . $accessTokenSecret . "\n";
print 'user_id = ' . $userId . "\n";
print 'screen_name  = ' . $screenName . "\n";

// Save this access token for future calls.
// Just in case we need user_id and screen_name, save those also..
$json = new COM("Chilkat.JsonObject");
$json->AppendString('oauth_token',$accessToken);
$json->AppendString('oauth_token_secret',$accessTokenSecret);
$json->AppendString('user_id',$userId);
$json->AppendString('screen_name',$screenName);

$fac = new COM("Chilkat.FileAccess");
$fac->WriteEntireTextFile('qa_data/tokens/twitter.json',$json->emit(),'utf-8',0);

print 'Success.' . "\n";

?>