Sample code for 30+ languages & platforms
PHP Extension

Trello OAuth1 Authorization

See more OAuth1 Examples

Demonstrates OAuth1 authentication for Trello.

Chilkat PHP Extension Downloads

PHP Extension
<?php

include("chilkat.php");

$success = false;

// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.

$consumerKey = 'TRELLO_CONSUMER_KEY';
$consumerSecret = 'TRELLO_CONSUMER_SECRET';

$requestTokenUrl = 'https://trello.com/1/OAuthGetRequestToken';
$authorizeUrl = 'https://trello.com/1/OAuthAuthorizeToken';
$accessTokenUrl = 'https://trello.com/1/OAuthGetAccessToken';

// 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 CkHttp();

$http->put_OAuth1(true);
$http->put_OAuthConsumerKey($consumerKey);
$http->put_OAuthConsumerSecret($consumerSecret);
$http->put_OAuthCallback($callbackUrl);

$req = new CkHttpRequest();
$req->put_HttpVerb('POST');
$req->put_ContentType('application/x-www-form-urlencoded');

$resp = new CkHttpResponse();
$success = $http->HttpReq($requestTokenUrl,$req,$resp);
if ($success == false) {
    print $http->lastErrorText() . "\n";
    exit;
}

// If successful, the resp.BodyStr contains something like this:  
// oauth_token=c173ff088a09a67389a42b1ee22366a4&oauth_token_secret=717e6015c6749fe050a923516e739dbb&oauth_callback_confirmed=true
print $resp->bodyStr() . "\n";

$hashTab = new CkHashtable();
$hashTab->AddQueryParams($resp->bodyStr());

$requestToken = $hashTab->lookupStr('oauth_token');
$requestTokenSecret = $hashTab->lookupStr('oauth_token_secret');
$http->put_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 CkStringBuilder();
$sbUrlForBrowser->Append($authorizeUrl);
$sbUrlForBrowser->Append('?oauth_token=');
$sbUrlForBrowser->Append($requestToken);
$sbUrlForBrowser->Append('&scope=read,write,account');

$url = $sbUrlForBrowser->getAsString();

print 'url = ' . $url . "\n";

// When the urlForBrowser is loaded into a browser, the response from Trello 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 CkSocket();

$backLog = 5;
$success = $listenSock->BindAndListen($callbackLocalPort,$backLog);
if ($success == false) {
    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 CkSocket();
$maxWaitMs = 60000;
// task is a CkTask
$task = $listenSock->AcceptNextAsync($maxWaitMs,$sock);
$task->Run();

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

// Wait for the listenSock's task to complete.
$success = $task->Wait($maxWaitMs);
if (!$success or ($task->get_StatusInt() != 7) or ($task->get_TaskSuccess() != true)) {
    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->get_LastMethodSuccess() == false) {
    print $sock->lastErrorText() . "\n";
    exit;
}

// Read the request header.
$requestHeader = $sock->receiveUntilMatch('\r\n\r\n');
if ($sock->get_LastMethodSuccess() == false) {
    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 CkStringBuilder();
$sbResponseHtml->Append('<html><body><p>Chilkat thanks you!</b></body</html>');

$sbResponse = new CkStringBuilder();
$sbResponse->Append('HTTP/1.1 200 OK\r\n');
$sbResponse->Append('Content-Length: ');
$sbResponse->AppendInt($sbResponseHtml->get_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 something like this:
//  GET /?oauth_token=c173ff088a09a67389b42b1ee32366a4&oauth_verifier=c65bc8eed882e04bb94023bb12c0dbef HTTP/1.1
$sbStartLine = new CkStringBuilder();
$sbStartLine->Append($startLine);
$numReplacements = $sbStartLine->Replace('GET /?','');
$numReplacements = $sbStartLine->Replace(' HTTP/1.1','');
$sbStartLine->Trim();

// oauth_token=c173ff088a09a67389b42b1ee32366a4&oauth_verifier=c65bc8eed882e04bb94023bb12c0dbef
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->put_OAuthToken($requestToken);
$http->put_OAuthVerifier($authVerifier);$req->put_HttpVerb('POST');

$req->put_HttpVerb('POST');
$req->put_ContentType('application/x-www-form-urlencoded');

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

// Make sure a successful response was received.
if ($resp->get_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=4618e19f5101b7199f75aA9e678d1585576ad84fb89fa40c85c4da13589010d5&oauth_token_secret=64a997b26ea1f47105eca36ce1a5d22e
print 'response BodyStr = ' . $resp->bodyStr() . "\n";

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

$accessToken = $hashTab->lookupStr('oauth_token');
$accessTokenSecret = $hashTab->lookupStr('oauth_token_secret');

// 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";

// Save the access token for subsequent REST API calls.
$json = new CkJsonObject();
$json->AppendString('oauth_token',$accessToken);
$json->AppendString('oauth_token_secret',$accessTokenSecret);

$fac = new CkFileAccess();
$fac->WriteEntireTextFile('qa_data/tokens/trello.json',$json->emit(),'utf-8',false);

print 'Success.' . "\n";

?>