Finally, we will expound on Part 5 to show how to form signed requests. As said, making API calls (resource requests) is the most tricky part of OAuth. Let’s look at the four steps to making signed requests: send parameters, base string, signature, and sending the request.
5. Resource Request
It is assumed at this point that everything previously discussed in this tutorial is understood. Explaining the technicals of making API calls demands it. In fact, the second and fourth steps mentioned last time directly tie into this part. So, moving on, here we are looking at a specific kind of API call: a resource request. Hands down, this is where anyone attempting OAuth succeeds or fails. The resource requests must be formed perfectly. There are four key steps to any resource request: the send parameters, the base string, the signature, and the sending of the request.
i. Send Parameters
The first step is to set and gather the send parameters. The following two steps will be for forming the oauth_signature that is required in these parameters, but here we will set the values we know in order to perform the next step, the base string. There are 7 parameters that the OAuth specification requires for any resource request:
- oauth_token (access token)
- oauth_timestamp (see RFC for specs)
- oauth_nonce (see RFC for specs)
Here are a list of items to note and tips about the send parameters:
- The service provider is allowed to specify some of the above send parameters as not necessary. Even though they are specified as required in the RFC. (Why!?)
- Every resource endpoint will have its own optional and required parameters. Any good API will tell you what parameters are required and allowed.
ii. Base String
The second step is to form the base string which will then be used for computing the signature. The base string is formed by concatenating the following strings:
- The uppercase HTTP request method (POST or GET)
- An ampersand (&)
- The normalized url
- An ampersand (&)
- The normalized parameters
The HTTP request method will be specified by the API and often depends on what resource is being accessed. The normalized URL is just a fancy term for taking the URL of the resource endpoint and percent encoding it. The normalized parameters are made by (1) encoding the names and values (separately), (2) sorting the name/value pairs by name then value using ascending byte value ordering, (3) combining them with an equal sign (i.e. param1=my%20value), and then (4) concatenating the whole set of name/value pairs by ampersands (i.e. param1=my%20value¶m2=&fancy%20name=true). Concatenate all that together and you will get something like:
Here are some notes and tips when forming the base string:
- The oauth_signature is not included in the base string. If you think about it, it wouldn’t make sense because it would always be empty and if you add in the signature after you’ve already taken the signature of the request then the request has changed, therefore the base string has changed, and therefore the signature has changed.
- Getting the base string right is likely the cause of 99% of the problems you encounter when dealing with OAuth. Thus, check to make sure the base string is correct first.
- Use a service like the Apigee Console to see if you are forming the base string right.
- If your signature is wrong, as said, 99% of the time it’s because your base string is wrong. Get the values from a base string of a request you know works, then hard code those values into your app and see if the signature your code produces matches the one you know works.
The signature would be the hardest part if there weren’t any libraries for the SHA1 algorithm. Two signature methods are RSA-SHA1 and PLAINTEXT, but HMAC-SHA1 is the most popular. The signature that results from using this method is called a digest and it is computed by feeding the HMAC-SHA1 algorithm two things: the base string and a signature key. The signature key is formed by concatenating the following strings:
- The encoded consumer_secret
- An ampersand (&)
- The encoded oauth_token_secret (access token secret)
The signature (digest) then is set in the send parameters. Here are some notes and tips when forming the signature:
- When performing the request token request (step 2) the oauth_token_secret will be left blank.
- When performing the access token request (step 4) the oauth_token_secret will be set to the request token secret.
- Take note of the last tip above on forming the base string. Being able to compare base strings and signatures with ones you know work is vital to diagnosing OAuth issues.
iv. Sending the Request
Now, for the final step: actually sending the request. The request will be an XHR call, as previously explained, to a resource endpoint that will send the parameters we just completed. These send parameters may be sent in one of two ways: the HTTP ‘Authorization’ header or the HTTP request entity body. How these parameters are sent is highly technical, as the RFC shows.
- The string that is set as the ‘Authorization’ header and the entity body are formed the exact same way.
- You do not need to send the parameters via the ‘Authorization’ header and the entity body; any good API will tell you which is needed.
- If sending the parameters via the entity body the ‘Content-Type’ header must be set to ‘application/x-www-form-urlencoded’.
- The URL for the resource endpoint you are sending the request to is the exact same as the URL used in the base string.
Debugging resource requests is nearly impossible:
- The request tokens are one-time use and expire quickly.
- In some cases, even access tokens expire.
- OAuth is implemented differently for almost every service.
- OAuth operates on a very elementary level, i.e. there is no GUI or debug console.
- The tools to debug (such as telnet) require a lot of technical skill and knowledge of the HTTP protocol as well as OAuth.
After all of this has been said and you understand what OAuth does, why OAuth? It is worth mentioning that there are other authorization protocols out there. There is AuthSub and ClientLogin which are proprietary Google protocols similar to OAuth but they also handle authentication. There is also OpenID, which often gets confused with OAuth though the two are distinctly different. In fact, Google has produced the “Hybrid protocol” which combines OAuth and OpenID. The fact is, there is an enormous demand for web security and OAuth currently provides the best solution for authorization.