次の方法で共有


Using WinRT’s WebAuthenticationBroker with Flickr’s OAuth API – Part 2

Part 2: Get User’s Authorization and Exchange Request Token for an Access Token

In the first part of this article, I discussed obtaining the Request Token during the authentication process using OAuth protocol in a sample Windows Store App for Windows 8.

In this part, I’ll discuss the next two steps in the authentication flow for OAuth 1.0:

  1. Get a Request Token
  2. Get the User's Authorization
  3. Exchange the Request Token for an Access Token

 

2. Get the User’s Authorization

After receiving the Request Token, we need to send it to Flickr’s API for User’s authorization. The Request Token is sent by appending it to the query string of the following URL with optional ‘perms’ argument.

Sample URL to get User authorization:

https://secure.flickr.com/services/oauth/authorize?oauth_token=87634kjbkjhuy89369hjkh&perms=write

I refer to the above URL as ‘Login link’ in this article. My next step would be to write a function that would return this Login link.

In the previous article, I discussed the process of generating the basic parameters, calculating the signed URL, and obtaining Request Token. I would be calling each of these respective methods in my GetLoginLink() method.

C#

public async static Task<string> GetLoginLink()
        {
            string baseUrlForRequestToken = "https://secure.flickr.com/services/oauth/request_token";
            //Get basic parameters
            Dictionary<string, string> parameters = OAuth1Helper.GetOAuthParameters(apikey, redirectUrl);
            //Get signed url
            string signedUrl = OAuth1Helper.CalculateOAuthSignedUrl(parameters, baseUrlForRequestToken, secretkey, false);
            //send the signed url to flickr
            string response = await OAuth1Helper.GetResponseFromWeb(signedUrl);
            OAuth1Helper.SetRequestToken(response);
            return "https://secure.flickr.com/services/oauth/authorize?oauth_token=" + OAuth1Helper.OAuth_token + "&perms=write";
        }

Figure 1: Get the Login link

Going back to the topic of WebAuthenticationBroker discussed in part 1, I went over the parameters that I needed before I call WebAuthenticationBroker’s AuthenticateAsync() method. Now that I have all my parameters ready, I’ll write my event handler for the Login button as follows:

C#

private async void loginButtonClicked(object sender, RoutedEventArgs e)
        {
            string output;
            Uri flickrUri = new Uri(await SampleDataSource.GetLoginLink());
            WebAuthenticationResult webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
                                                    WebAuthenticationOptions.None,
                                                    flickrUri, new Uri(SampleDataSource.redirectUrl));

            if (webAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success)
            {
                output = webAuthenticationResult.ResponseData.ToString();
                await SampleDataSource.GetAccessToken(output);
                this.DefaultViewModel["MessageDisplay"] = true;
                this.DefaultViewModel["Message"] = "Welcome, " + SampleDataSource.username + "!";
                this.DefaultViewModel["DisplayLogin"] = false;
            }
            else if (webAuthenticationResult.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
            {
                output = "HTTP Error returned by AuthenticateAsync() : " + webAuthenticationResult.ResponseErrorDetail.ToString();
            }
            else if (webAuthenticationResult.ResponseStatus == WebAuthenticationStatus.UserCancel)
            {
                output = "Authentication process was cancelled by the user";
            }
        }

Figure 2: Event handler for Login button

When I hit the Login button, I am navigated to the following screen:

image5_thumb

Figure 3: Login screen in the App container

I enter my enter credentials and hit the Sign In button.

After I am successfully logged in, the following screen appears:

image_thumb[4]

Figure 4: User Authorization screen – User authorizes the Request Token

When I hit the “OK, I’ll AUTHORIZE IT” button, Flickr authorizes the Request Token that I obtained in the Step 1 and sends back an authorized Request Token. The response sent back by the Flickr API gets populated in  webAuthenticationResult.ResponseData (as shown in Figure 2).

Sample response returned by Flickr looks similar to this:

<redirect URL placeholder>?oauth_token=3345464353453458-022bbgttyt3542f3432 &oauth_verifier=45dererer6b67074

3. Exchange Request Token for Access Token

As a next step in this process, I need to parse the response received in the above step and extract the authorized Request Token and prepare for exchanging it with Access Token. To get the Access Token I need to follow the same steps as needed for obtaining the Request Token (discussed in part 1). They are:

  1. Get basic parameters
  2. Calculate signed URL
  3. Send the signed URL and get response
  4. Parse the response and extract Token

The base URL for Access Token would be:

https://secure.flickr.com/services/oauth/access_token

The following method parses the response string, extracts the oauth_token and oauth_verifier received in Step 2, and calculates the signed URL. This signed URL is finally passed on to the Flickr’s API and the Request Token is exchanged for Access token. Besides the CalculateAccessToken() method defined in Figure 6, rest of the methods are defined in part 1 of this article series.

C#

public static async Task GetAccessToken(string responseData)
        {
            string oauth_token = null;
            string oauth_verifier = null;
            String[] keyValPairs = responseData.Split('&');
            string baseUrlForAccessToken = "https://secure.flickr.com/services/oauth/access_token";
            //parses the response string
            for (int i = 0; i < keyValPairs.Length; i++)
            {
                String[] splits = keyValPairs[i].Split('=');
                if (splits[0].Contains("oauth_token"))
                {
                    oauth_token = splits[1];
                }
                else if (splits[0].Contains("oauth_verifier"))
                {
                    oauth_verifier = splits[1];
                }
            }

            //Get basic parameters
            Dictionary<string, string> parameters = OAuth1Helper.GetOAuthParameters(apikey, redirectUrl);
            parameters.Add("oauth_verifier", oauth_verifier);
            parameters.Add("oauth_token", oauth_token);
            string signedUrl = OAuth1Helper.CalculateOAuthSignedUrl(parameters, baseUrlForAccessToken, secretkey, true);
            string response = await OAuth1Helper.GetResponseFromWeb(signedUrl);
            CalculateAccessToken(response);
        }

 

Figure 5: Exchange Request Token for Access Token

Sample response from Flickr containing the Access Token looks similar to this:

fullname=Jamal%20Fanaian& oauth_token=72157626318069415-087bfc7b5816092c & oauth_token_secret=a202d1f853ec69de& user_nsid=21207597%40N07& username=jamalfanaian

After I receive a response from the Flickr API, I need to extract the Access Token and save it for sending authorized requests to Flickr APIs’.

C#

public static void CalculateAccessToken(string responseData)
        {
            String accessToken = null;
            String accessTokenSecret = null;
            String[] keyValPairs = responseData.Split('&');
            string username = string.Empty;
            for (int i = 0; i < keyValPairs.Length; i++)
            {
                String[] splits = keyValPairs[i].Split('=');
                switch (splits[0])
                {
                    case "oauth_token":
                        accessToken = splits[1];
                        break;
                    case "oauth_token_secret":
                        accessTokenSecret = splits[1];
                        break;
                    case "username":
                        username = splits[1];
                        break;
                }
            }
            // Set current access token.
            SampleDataSource.flickr.OAuthAccessToken = accessToken;
            SampleDataSource.flickr.OAuthAccessTokenSecret = accessTokenSecret;
            SampleDataSource.username = username;
            Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
            Windows.Storage.ApplicationDataCompositeValue composite = new Windows.Storage.ApplicationDataCompositeValue();
            composite["accessToken"] = accessToken;
            composite["accessTokenSecret"] = accessTokenSecret;
            composite["username"] = username;
            roamingSettings.Values["accessCompositeSetting"] = composite;
        }

Figure 6: Extract and Save the Access Token

In my App, I load the application settings next time the App loads and retrieve the credentials as shown below:

C#

public static void RetrieveCredentials()
        {
            Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
            Windows.Storage.ApplicationDataCompositeValue composite =
               (Windows.Storage.ApplicationDataCompositeValue)roamingSettings.Values["accessCompositeSetting"];

            if (composite == null)
            {
                SampleDataSource.isUserAuthenticated = false;
            }
            else
            {
                SampleDataSource.isUserAuthenticated = true;
                SampleDataSource.username = composite["username"].ToString();
                SampleDataSource.flickr.OAuthAccessToken = composite["accessToken"].ToString();
                SampleDataSource.flickr.OAuthAccessTokenSecret = composite["accessTokenSecret"].ToString();
            }
        }

Once the credentials are retrieved, subsequent calls can be made to the various Flickr APIs’ for data exchange.

Here is an example call using the Access Token to the flickr.test.login API listed on the Flickr’s website:

https://api.flickr.com/services/rest ?nojsoncallback=1 &oauth_nonce=84354935& format=json& oauth_consumer_key=653e7a6ecc1d528c516cc8f92cf98611& oauth_timestamp=1305583871& oauth_signature_method=HMAC-SHA1& oauth_version=1.0& oauth_token=72157626318069415-087bfc7b5816092c& oauth_signature=dh3pEH0Xk1qILr82HyhOsxRv1XA%3D& method=flickr.test.login

You may want to check Flickr’s documentation to further understand the use of tokens in your calls to the Flickr API for data exchange.

 

Resources:

  • I have used the Web authentication broker sample provided here.
  • I have used Flickr.Net library listed on their website for making API calls.

Comments

  • Anonymous
    August 12, 2013
    Really would be more productive if you showed the OAuth1Helper.GetOAuthParameters() method implementation.

  • Anonymous
    August 12, 2013
    Sorry, the implementation was on last post :D

  • Anonymous
    August 13, 2013
    Great!! You could find it :)

  • Anonymous
    January 23, 2016
    Sorry but i can not find the OAuth1Helper implementation.