Understanding Request Signing For Oauth 1.0a Providers

I am very familiar with Oauth 2.0, but recently I had to work with Twitter and it was not as smooth of an experience as other providers such as Google and Facebook. This is because Twitter uses Oauth 1.0a and requires request signing.

Oauth 1.0a requires requests to be signed using HMAC and a secret key. Using this protects communication between the client and the server, but how do we accomplish this task?

Creating a signature happens through the following steps:

Collect required parameters

Collect query string and body parameters

Create a signature base string

Hash with HMAC and a secret key

Use the signature in your request

For the sake if this article, there will be some heavy references to JavaScript, but you can apply this knowledge to any programming language.

1. Collect required parameters

Twitter, like all Oauth 1.0a providers have a set of required parameters. They will probably be similar if not the same across all providers. Let’s look at the following required elements:

All of the above properties will have static values provided by the Oauth provider except the oauth_nonce and oauth_timestamp. These are dynamic values that must be set during run time. The nonce is a random string value, something I normally set as a hash of the timestamp. The timestamp is the time from epoch.

If using JavaScript, you can get the epoch by running the following:

var oauth_timestamp = Math.round((new Date()).getTime() / 1000.0);

With the required parameters in hand, you can now start collecting the query and body parameters.

2. Collect query string and body parameters

All parameters, query and body, must be collected before creating a signature base string. In addition, each of these parameters must be percent encoded. Let’s assume we are doing a POST request and there is only one body parameter called oauth_callback. Our new parameter list now looks like the following:

With all parameters collected we can move on to creating a signature base string.

3. Create a signature base string

The signature base string has some very strict requirements, but it is the final string that will be hashed using the appropriate hashing algorithm. The base string must be formatted like the following:

POST&REQUEST_URI&PARAMETERS

Let’s assume for this example we are going to use the https://api.twitter.com/oauth/request_token endpoint. The generic format I posted above, is far to general for what we need to accomplish. To be more specific, the request uri and all parameters need to be percent encoded. In addition to being percent encoded, the parameters need to be in alphabetical order. To accomplish this, you might do something like the following in JavaScript:

4. Hash with HMAC and a secret key

We will now create a hashed signature string from our signature base string. If you’re using Twitter, the requirement is HMAC-SHA1 which isn’t necessarily the strongest form of SHA, but it works.

Note that you cannot use your raw consumer secret key to sign the request. You must concatenate the secret key and Oauth token secret provided by your Oauth provider for signing. These must be concatenated with an ampersand.

If you’re using PHP, don’t forget to convert the HEX $signature string to a BASE64 encoded $signature string. If you wanted to do this with JavaScript, I highly recommend using the open source jsSHA library as it has some really great hashing algorithms including HMAC-SHA1. With jsSHA your signature would be generated like follows:

Note that I made up all the values above, but the keys are accurate. Only the required parameters show up in the header. The query and body parameters do not show up in the header, only in the query and body.

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.