READ THIS FIRST

Update: 3-4-2016: If you're finding this blog and looking for information related to Azure Mobile Services, I'd strongly recommend checking out Azure Mobile Apps. Azure Mobile Apps is a new version (consider it a v2) of Azure's mobile backend support. All of the same features of Azure Mobile Services are there, with a lot of other very cool features to go along. You can read more about Azure Mobile Apps, and how to transition from Azure Mobile Services, here.

Recently I had someone reach out to me as they were trying to communicate from their Windows Azure Mobile Service scripts to Twitter’s API and were running into issues.  At first I didn’t understand why as everything was working for me.  I then discovered that I had been using version 1.0 of the Twitter API while they were using the new 1.1 version.  After a little bit of work I was able to figure out how to get through to the 1.1 API with an authenticated request from Mobile Service scripts.  With the upcoming retirement of version 1.0 of the API on June 11th, I felt it was important to share with people how they could also access the updated API.  It’s important to note that if your application is currently using v1 of the API, it will NOT work as of June 11th.  This includes if you followed along with the steps in my extensive Authentication sample from a couple weeks ago (where I’m using v1 of the Twitter API to get the username).  Today we’ll look at the same situation, pulling the current user’s username.  However, you could use the same approach for any of the API methods.

A word on complexity

One of the first things you’ll notice when you look at this script is that it is pretty intense.  If you were going to access Twitter from more than one script, you’d have to copy and paste a lot of the same code into your scripts resulting in some very messy scripts.  We’re working on a solution to this but I can’t share any more details yet. 

Accessing v1.1 of the Twitter API

With v1, you were able to make what was considered “unauthenticated” requests.  This concept is gone (as far as I know) in v1.1.  Authorizing a request is a slightly complicated process that involves creating a signature which is pretty complex.  I’ll start by sharing the script with you and then trying to walk through individual pieces of it.  Note that I’ve left all of my keys, tokens, and secrets in the script so it will be easier for you to compare them to your own when you’re setting this up.  I’ve already removed the application so if you try to use this script exactly as is without setting your own information, it won’t work:

Setting up

At the top you can see that we’re getting access to the crypto and querystring modules.  We’ll need these later on.  Next we generate a result object which is what we’ll return to the calling app later on.  Commented out I have the single line of code that was needed to talk to v1 of the API to do what we’re going to accomplish here.  Right at the //API 1.1 comment is where we start the process of getting our signature and url ready for v1.1.  The URL we’re hitting is /users/show.json (you can view the different API methods here).  They key is your consumer key which you can access in the Details area once you’ve created your app in Twitter:

Twitter OAuth Settings

We then create a nonce.  This is a unique token that our app needs toe generate for each request.  Twitter uses this value to determine if the same request has been submitted multiple times.  We then indicate the signature method we’re using (HMAC-SHA1) and the version.  We specify our oauth_token which matches up with the Access Token at the bottom of the Twitter details page (you may need to click a button to generate an Access Token first):

Twitter Access Token

Next we get the seconds since the epoch (rounded) and specify that we’re making a GET request.  If  you use a different method that requires a POST, make sure you change this or it won’t work.

Building the signature

Now that are variables are created, we can get into the meat of actually generating the signature.  As mentioned before, the signature is fairly complex so you may want to review the documentation here.  The first thing we do is create an array (oauthData) which the key Twitter expects and the value we’re sending over.  We then loop through that array and add each value to a sigData array.  We also add the twitter ID to sigData (but not to oauthData).  Next we call generateOAuthSignature and pass in the request type, the URL, and the sigData array. 

GenerateOAuthSignature

Let’s take another look at this method:

We’re first getting the URL without any querystring parameters added to it (this is the format Twitter expects it in as part of the signature).  We then generate a signing token using the Consumer Secret (from the first picture above) and the Access Token Secret (from the second picture).  We then loop through the data array passed in and pull out each key (except the oauth_signature one) and put them in the keys array.  After that we sort them (Twitter expects them to be in alphabetical order).  We can then build our string using the request type, the url, and each key and data component, all of which has to be url encoded.  If we were to print out the output+params before we called hashString on it, we’d get something like this:

GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fusers%2Fshow.json&oauth_consumer_key%3D8PDPZfA7KWbXHdDGuSCbeg%26oauth_nonce%3D82031035513841026035%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1368129699%26oauth_token%3D915248383-qr3pkFBxqt1VRoOC5QlZdEmTBQboiui1YNgE3P3G%26oauth_version%3D1.0%26user_id%3D915248383

The hashString method then has the job of using crypto to hash the data together:

We end up getting something out that looks like this:

uH1G+uAbsQxCn5Oe1teTW3N7RFk=

Back to the main method

Now that we’ve generated our signature, we return back to the main method where we set the oauth_signature property in the oauthData array.  We then create a new variable, oauthHeader, which we fill by looping through the oauthData.  After that we chop off the leading comma and have a string that looks like this:

oauthheader: , oauth_consumer_key="8PDPZfA7KWbXHdDGuSCbeg", oauth_nonce="10312863624286267430", oauth_signature="tBSYJ7pshewhix9SRPvPnRMflE0%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1368130031", oauth_token="915248383-qr3pkFBxqt1VRoOC5QlZdEmTBQboiui1YNgE3P3G", oauth_version="1.0"

This, with the string OAuth prepended to it, is finally our Authorization header. 

Making the request

The rest of the code is the same as it would have been with v1.0.  We create a request callback that will be called when Twitter responds.  Inside of that callback, we attempt to parse the data and pull out the username which we set on the result object before returning to the calling app.  Finally, we use the request module to generate a new request and set the Authorization header using the value we previously created and then actually make the request.

Conclusion

As you’ve seen, calling into Twitter’s v1.1 API is entirely doable from Mobile Services’ scripting layer, it just takes a good amount of code to do it.  We’ll have a better way of handling all of this code at some point in the future but for now, you should be able to copy and paste most of this.  Remember that you need to replace the Consumer Key, Access Token, Consumer Secret, and Access Token Secret with your own values before you’ll be able to run the script. 


Chris Risner


8 Comments

Chris

I'm not sure if the users/show api will work with application only auth. However, there is a much simpler way to talk to the Twitter API (that I still need to post about). Take a look at https://github.com/WindowsA.... Specifically, check out where it's using the OAuth module to call the users/show api. I'll be posting about that soon.

byr8n

Hi Chris,
I'd like to grab the user's display name or real name and profile image from whichever service they log in through (Google, Facebook, Microsoft, or Twitter). Ideally that could happen in my Azure Mobile Services scripting layer when I go to create their user record. Do you know of any tutorials or libraries out there that work through that? I noted the one above you mentioned handles twitter.

Thanks for any info!

byr8n

Thanks, Chris. I found that after posting. It was a big help. Really appreciate all the posts you've done iOS related.

Leave a Comment