Introduction

 An example showing how OAuth Twitter API works step by step. (Updated for Twitter API v1.1 and query parameter support)

Description

Twitter is using a strict OAuth 1.0a and requires HTTP Header-based Authorization. Before we start coding, let’s talk briefly what our application (i.e., Twitter consumer) has to do to be able to consume Twitter information with user authorization.

1. Our application has to have a Twitter consumer key and consumer secret key. We can get it by registering your app through http://dev.twitter.com.

2. Our application starts talking with Twitter by asking Twitter for a request token (and request token secret key). In this step, our application has to give Twitter , the consumer key and other OAuth parameters like nonce, signature method, version, and so on. The application also needs to provide a signature which is signed with the consumer secret key.

3. Twitter gives us the request token and the request token secret key only (unlike LinkedIn), so we have to combined tokens and Twitter authorize url to let our user authorize our application.

4. As our application is not a web application (callback url was not specified), our application has to provide a way for user to enter a PIN code that Twitter gives the user in authorization process.

5. Now our application should have the request token, the request token secret key, the PIN code (oauth_verifier). Our application will use above information to request Twitter for an access token and an access token secret key. The application also needs to provide a signature which is signed with the consumer secret and request token secret keys .

6. Once our application has the access token and the access token secret key, then our application can make Twitter API call and get information from Twitter.

To see how signature is created, please go to https://dev.twitter.com/docs/auth/creating-signature.

Here are screenshots of the app.

 

 

 

How parameter base strings have been created:

 

 

C#
Edit|Remove
private string getParamsBaseString(string queryParamsString, string nonce, string timeStamp) 
        {            
            // these parameters are required in every request api 
            var baseStringParams = new Dictionary<stringstring>{ 
                {"oauth_consumer_key", consumerKey.Text}, 
                {"oauth_nonce", nonce}, 
                {"oauth_signature_method""HMAC-SHA1"}, 
                {"oauth_timestamp", timeStamp}, 
                {"oauth_token", accessToken.Text}, 
                {"oauth_verifier", oAuthVerifier.Text}, 
                {"oauth_version""1.0"},                 
            }; 
 
            // put each parameter into dictionary 
            var queryParams = queryParamsString 
                                .Split('&')                                 
                                .ToDictionary(p => p.Substring(0, p.IndexOf('=')), p => p.Substring(p.IndexOf('=')+1)); 
 
            foreach (var kv in queryParams) 
            { 
                baseStringParams.Add(kv.Key, kv.Value); 
            } 
 
            // The OAuth spec says to sort lexigraphically, which is the default alphabetical sort for many libraries. 
            var ret = baseStringParams 
                .OrderBy(kv => kv.Key) 
                .Select(kv => kv.Key + "=" + kv.Value) 
                .Aggregate((i, j) => i + "&" + j); 
 
            return ret; 
        }
How the request has been done:
C#
Edit|Remove
private async void requestTwitterApi(string url) 
        { 
            string nonce = oAuthUtil.GetNonce(); 
            string timeStamp = oAuthUtil.GetTimeStamp(); 
 
            try 
            { 
                HttpClient httpClient = new HttpClient(); 
                httpClient.MaxResponseContentBufferSize = int.MaxValue; 
                httpClient.DefaultRequestHeaders.ExpectContinue = false; 
                HttpRequestMessage requestMsg = new HttpRequestMessage(); 
                requestMsg.Method = new HttpMethod("GET"); 
 
                var qParams = QueryParams.Text; 
                var urlWithParams = url + "?" + qParams; 
                // HttpClient uses full url 
                requestMsg.RequestUri = new Uri(urlWithParams); 
 
                string paramsBaseString = getParamsBaseString(qParams, nonce, timeStamp); 
 
                string sigBaseString = "GET&"; 
                // signature base string uses base url 
                sigBaseString += Uri.EscapeDataString(url) + "&" + Uri.EscapeDataString(paramsBaseString); 
                 
                string signature = oAuthUtil.GetSignature(sigBaseString, consumerSecretKey.Text, accessTokenSecretKey.Text); 
                string data = "oauth_consumer_key=\"" + consumerKey.Text 
                              + 
                              "\", oauth_nonce=\"" + nonce + 
                              "\", oauth_signature=\"" + Uri.EscapeDataString(signature) + 
                              "\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"" + timeStamp + 
                              "\", oauth_token=\"" + accessToken.Text + 
                              "\", oauth_verifier=\"" + oAuthVerifier.Text +                                                            
                              "\", oauth_version=\"1.0\""; 
                requestMsg.Headers.Authorization = new AuthenticationHeaderValue("OAuth", data);                 
                var response = await httpClient.SendAsync(requestMsg); 
                var text = await response.Content.ReadAsStringAsync(); 
                WebViewHost.Visibility = Windows.UI.Xaml.Visibility.Collapsed; 
                TwitterResponse.Visibility = Windows.UI.Xaml.Visibility.Visible; 
                TwitterResponse.Text = text; 
            } 
            catch (Exception Err) 
            { 
                throw; 
            } 
        }