Sample code for 30+ languages & platforms
Lianja

Trello OAuth1 Authorization

See more OAuth1 Examples

Demonstrates OAuth1 authentication for Trello.

Chilkat Lianja Downloads

Lianja
llSuccess = .F.

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

lcConsumerKey = "TRELLO_CONSUMER_KEY"
lcConsumerSecret = "TRELLO_CONSUMER_SECRET"

lcRequestTokenUrl = "https://trello.com/1/OAuthGetRequestToken"
lcAuthorizeUrl = "https://trello.com/1/OAuthAuthorizeToken"
lcAccessTokenUrl = "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..
lcCallbackUrl = "http://localhost:3017/"
lnCallbackLocalPort = 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
loHttp = createobject("CkHttp")

loHttp.OAuth1 = .T.
loHttp.OAuthConsumerKey = lcConsumerKey
loHttp.OAuthConsumerSecret = lcConsumerSecret
loHttp.OAuthCallback = lcCallbackUrl

loReq = createobject("CkHttpRequest")
loReq.HttpVerb = "POST"
loReq.ContentType = "application/x-www-form-urlencoded"

loResp = createobject("CkHttpResponse")
llSuccess = loHttp.HttpReq(lcRequestTokenUrl,loReq,loResp)
if (llSuccess = .F.) then
    ? loHttp.LastErrorText
    release loHttp
    release loReq
    release loResp
    return
endif

// If successful, the resp.BodyStr contains something like this:  
// oauth_token=c173ff088a09a67389a42b1ee22366a4&oauth_token_secret=717e6015c6749fe050a923516e739dbb&oauth_callback_confirmed=true
? loResp.BodyStr

loHashTab = createobject("CkHashtable")
loHashTab.AddQueryParams(loResp.BodyStr)

lcRequestToken = loHashTab.LookupStr("oauth_token")
lcRequestTokenSecret = loHashTab.LookupStr("oauth_token_secret")
loHttp.OAuthTokenSecret = lcRequestTokenSecret

? "oauth_token = " + lcRequestToken
? "oauth_token_secret = " + lcRequestTokenSecret

// ---------------------------------------------------------------------------
// 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.
loSbUrlForBrowser = createobject("CkStringBuilder")
loSbUrlForBrowser.Append(lcAuthorizeUrl)
loSbUrlForBrowser.Append("?oauth_token=")
loSbUrlForBrowser.Append(lcRequestToken)
loSbUrlForBrowser.Append("&scope=read,write,account")

lcUrl = loSbUrlForBrowser.GetAsString()

? "url = " + lcUrl

// 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.
loListenSock = createobject("CkSocket")

lnBackLog = 5
llSuccess = loListenSock.BindAndListen(lnCallbackLocalPort,lnBackLog)
if (llSuccess = .F.) then
    ? loListenSock.LastErrorText
    release loHttp
    release loReq
    release loResp
    release loHashTab
    release loSbUrlForBrowser
    release loListenSock
    return
endif

// 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.
loSock = createobject("CkSocket")
lnMaxWaitMs = 60000
loTask = loListenSock.AcceptNextAsync(lnMaxWaitMs,loSock)
loTask.Run()

// Launch the system's default browser navigated to the URL.
loOauth2 = createobject("CkOAuth2")
llSuccess = loOauth2.LaunchBrowser(lcUrl)
if (llSuccess = .F.) then
    ? loOauth2.LastErrorText
    release loHttp
    release loReq
    release loResp
    release loHashTab
    release loSbUrlForBrowser
    release loListenSock
    release loSock
    release loOauth2
    return
endif

// Wait for the listenSock's task to complete.
llSuccess = loTask.Wait(lnMaxWaitMs)
if (not llSuccess or (loTask.StatusInt <> 7) or (loTask.TaskSuccess <> .T.)) then
    if (not llSuccess) then
        // The task.LastErrorText applies to the Wait method call.
        ? loTask.LastErrorText
    else
        // The ResultErrorText applies to the underlying task method call (i.e. the AcceptNextConnection)
        ? loTask.Status
        ? loTask.ResultErrorText
    endif

    release loTask
    release loHttp
    release loReq
    release loResp
    release loHashTab
    release loSbUrlForBrowser
    release loListenSock
    release loSock
    release loOauth2
    return
endif

// 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.
loListenSock.Close(10)

release loTask

// Read the start line of the request..
lcStartLine = loSock.ReceiveUntilMatch(Chr(13) + Chr(10))
if (loSock.LastMethodSuccess = .F.) then
    ? loSock.LastErrorText
    release loHttp
    release loReq
    release loResp
    release loHashTab
    release loSbUrlForBrowser
    release loListenSock
    release loSock
    release loOauth2
    return
endif

// Read the request header.
lcRequestHeader = loSock.ReceiveUntilMatch(Chr(13) + Chr(10) + Chr(13) + Chr(10))
if (loSock.LastMethodSuccess = .F.) then
    ? loSock.LastErrorText
    release loHttp
    release loReq
    release loResp
    release loHashTab
    release loSbUrlForBrowser
    release loListenSock
    release loSock
    release loOauth2
    return
endif

// 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.
loSbResponseHtml = createobject("CkStringBuilder")
loSbResponseHtml.Append("<html><body><p>Chilkat thanks you!</b></body</html>")

loSbResponse = createobject("CkStringBuilder")
loSbResponse.Append("HTTP/1.1 200 OK" + Chr(13) + Chr(10))
loSbResponse.Append("Content-Length: ")
loSbResponse.AppendInt(loSbResponseHtml.Length)
loSbResponse.Append(Chr(13) + Chr(10))
loSbResponse.Append("Content-Type: text/html" + Chr(13) + Chr(10))
loSbResponse.Append(Chr(13) + Chr(10))
loSbResponse.AppendSb(loSbResponseHtml)

loSock.SendString(loSbResponse.GetAsString())
loSock.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
loSbStartLine = createobject("CkStringBuilder")
loSbStartLine.Append(lcStartLine)
lnNumReplacements = loSbStartLine.Replace("GET /?","")
lnNumReplacements = loSbStartLine.Replace(" HTTP/1.1","")
loSbStartLine.Trim()

// oauth_token=c173ff088a09a67389b42b1ee32366a4&oauth_verifier=c65bc8eed882e04bb94023bb12c0dbef
? "startline: " + loSbStartLine.GetAsString()

loHashTab.Clear()
loHashTab.AddQueryParams(loSbStartLine.GetAsString())

lcRequestToken = loHashTab.LookupStr("oauth_token")
lcAuthVerifier = loHashTab.LookupStr("oauth_verifier")

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

loHttp.OAuthToken = lcRequestToken
loHttp.OAuthVerifier = lcAuthVerifierloReq.HttpVerb = "POST"

loReq.HttpVerb = "POST"
loReq.ContentType = "application/x-www-form-urlencoded"

llSuccess = loHttp.HttpReq(lcAccessTokenUrl,loReq,loResp)
if (llSuccess = .F.) then
    ? loHttp.LastErrorText
    release loHttp
    release loReq
    release loResp
    release loHashTab
    release loSbUrlForBrowser
    release loListenSock
    release loSock
    release loOauth2
    release loSbResponseHtml
    release loSbResponse
    release loSbStartLine
    return
endif

// Make sure a successful response was received.
if (loResp.StatusCode <> 200) then
    ? loResp.StatusLine
    ? loResp.Header
    ? loResp.BodyStr
    release loHttp
    release loReq
    release loResp
    release loHashTab
    release loSbUrlForBrowser
    release loListenSock
    release loSock
    release loOauth2
    release loSbResponseHtml
    release loSbResponse
    release loSbStartLine
    return
endif

// If successful, the resp.BodyStr contains something like this:
// oauth_token=4618e19f5101b7199f75aA9e678d1585576ad84fb89fa40c85c4da13589010d5&oauth_token_secret=64a997b26ea1f47105eca36ce1a5d22e
? "response BodyStr = " + loResp.BodyStr

loHashTab.Clear()
loHashTab.AddQueryParams(loResp.BodyStr)

lcAccessToken = loHashTab.LookupStr("oauth_token")
lcAccessTokenSecret = loHashTab.LookupStr("oauth_token_secret")

// The access token + secret is what should be saved and used for
// subsequent REST API calls.
? "Access Token = " + lcAccessToken
? "Access Token Secret = " + lcAccessTokenSecret

// Save the access token for subsequent REST API calls.
loJson = createobject("CkJsonObject")
loJson.AppendString("oauth_token",lcAccessToken)
loJson.AppendString("oauth_token_secret",lcAccessTokenSecret)

loFac = createobject("CkFileAccess")
loFac.WriteEntireTextFile("qa_data/tokens/trello.json",loJson.Emit(),"utf-8",.F.)

? "Success."


release loHttp
release loReq
release loResp
release loHashTab
release loSbUrlForBrowser
release loListenSock
release loSock
release loOauth2
release loSbResponseHtml
release loSbResponse
release loSbStartLine
release loJson
release loFac