OAuth and Flickr – Part 2

Continuing on from Part 1.

Update: I got the order of the parameters wrong below so my example signature was incorrect. I have now fixed that.

Update2: Flickr have updated to only using HTTPS endpoints. I won’t change the code below as then the signature generation would not match the output values, but bare this in mind.

Authenticating with Flickr

The process of authenticating with Flickr is a 3 stage process.

First you call the request token url and get back a request token and a request token secret.

Second you redirect the user to the authorize url and they approve your authentication request. Then they are either presented with a verification code on the screen, or the verification code is appended to your callback url.

Thirdly, once you have the verifier code you call the access token url to get your final access token.

Step 1 – Request a Request Token?

I have created an API key and shared secret especially for this tutorial which I will use below. Feel free to use this API key for testing, but do not use it for development – go get your own. The reason I provide this functionality here is so that you can test your signature generation function – if you use my api key and shared secret you should get exactly the same signature.

Signature Generation

This is the bit that catches most people out, and so I will go through this step by step.

First, you need to get your oauth parameters set.

Timestamp= “1316657628”
Nonce = “C2F26CD5C075BA9050AD8EE90644CF29”
Consumer Key = “768fe946d252b119746fda82e1599980”
Version = “1.0”
Signature Method =  “HMAC-SHA1”
Callback URL = “http://www.wackylabs.net/oauth/test”

Consumer Secret = “1a3c208e172d3edc”

To generate a SHA1 signature you require two things. First a key. For OAuth the signature key is made up of two parts, your consumer secret, and your token secret (for whichever token you are using at the time). As this is the first stage you have neither, so your token secret is simply an empty string.

Key = Consumer Secret + “&” + Token Secret
= “1a3c208e172d3edc&”

The second part of the SHA1 signature generation is the base string. For OAuth the base string is made up of three parts, the HTTP method, the URL endpoint you are using, and the parameters you are sending.

OAuth Parameter Encoding – Not your normal encoding

However the key to this part is the encoding. OAuth uses an encoding which is very similar to URL encoding (i.e. replacing parts of a URL string with %NN where NN is the hex number for that character). However it is different, in that more things are encoded when using OAuth encoding (e.g. spaces can be encoded as a “+” symbol in URL encoding, but in OAuth must be encoded as “%20”.

OAuth encoding only allows letters, numbers and the following 4 punctuation marks: “_”, “-“, “.” and “~”. All other characters must be encoded.

You will likely not notice the difference until you come to call methods that include things like title etc, as most parameters will not contain data that is encoded differently with the above compared to standard url encoding.

A little post I found covering some of the differences is here: http://www.marcworrell.com/article-2943-en.html

Bringing the Base String Together

For the first part of the base string then encoding doesn’t matter, as it will be either “GET” or “POST”. This is the same once encoded :)

For the second part your request url endpoint will get encoded to something like this:

“http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token”

For the final part of the base string you need to concatenate the encoded parameters and values as if you were generating a URL (except you are using oauth encoding), and then encode the whole lot again. The parameters must also be sorted in alphabetical order. Note, technically you are encoding both the parameter name and value, but as letters and the “_” character do not change after encoding the parameter names look the same after encoding.

So first you generate the following string (ignore carriage returns):

“oauth_callback=http%3A%2F%2Fwww.wackylabs.net%2Foauth%2Ftest&
oauth_consumer_key=768fe946d252b119746fda82e1599980&
oauth_nonce=C2F26CD5C075BA9050AD8EE90644CF29&
oauth_signature_method=HMAC-SHA1&oauth_timestamp=1316657628&
oauth_version=1.0”

And then you encode it again (again, ignore carriage returns):

“oauth_callback%3Dhttp%253A%252F%252Fwww.wackylabs.net%252Foauth%252Ftest%26
oauth_consumer_key%3D768fe946d252b119746fda82e1599980%26
oauth_nonce%3DC2F26CD5C075BA9050AD8EE90644CF29%26
oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1316657628%26
oauth_version%3D1.0”

Before finally adding it all together as part1 + “&” + part2 + “&” + part3 to give a final base string like so:

Base String = “GET&http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token&
oauth_callback%3Dhttp%253A%252F%252Fwww.wackylabs.net%252F
oauth%252Ftest%26oauth_consumer_key%3D768fe946d252b119746fda82e1599980%26
oauth_nonce%3DC2F26CD5C075BA9050AD8EE90644CF29%26
oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1316657628%26
oauth_version%3D1.0”

Finally you are ready to use whatever SHA1 code your programming language provides to generate the signature.

In .Net this might look like this:

byte[] keyBytes = System.Text.Encoding.UTF8.GetBytes(key); System.Security.Cryptography.HMACSHA1 sha1 = new System.Security.Cryptography.HMACSHA1(keyBytes); byte[] signatureBytes = sha1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(baseString)); string signature = Convert.ToBase64String(signatureBytes);

In PHP this might look like this:

$signature = base64_encode(hash_hmac(‘sha1’, $baseString, $key, true));

The important thing to notice with both of these examples is that you are returning binary data from the signature method, and then base 64 encoding this data. The hash_hmac() method in php can also return string data, but this will not work, so the fourth parameter is required to be set to true to return the raw binary data instead.

Using the above methods, and the above sample parameters the final signature is as follows:

Signature = “0fhNGlzpFNAsTme/hDfUb5HPB5U=”

Finally Request your Token

Now you have your signature you can create the url to actually request your request token with.

Note, when generating your URL you must again encode everything (including the new oauth_signature parameter) but you do not need to use the strict OAuth encoding, but can return to normal url encoding.

URL = “http://www.flickr.com/services/oauth/request_token?oauth_callback=http%3A%2F%2Fwww.wackylabs.net%2Foauth%2Ftest&oauth_consumer_key=768fe946d252b119746fda82e1599980&oauth_nonce=C2F26CD5C075BA9050AD8EE90644CF29&oauth_timestamp=1316657628&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_signature=0fhNGlzpFNAsTme%2FhDfUb5HPB5U%3D”

 Authorization Header

It is possible, rather than putting everything in the query string as above to put all of your oauth parameters in a special HTTP header instead.

OAuth parameter put into the Authorization header should be encoded using oauth encoding as for the generation of the base string. However the parameter values are enclosed in double quotes (“) and each parameter is separated by a comma.

All OAuth parameters then need removing from the request URL, in this case as they are ALL oauth parameter you are just left with the request_token endpoint.

So the header would look like this (line breaks and other white space are optional between the parameters in the header):

OAuth oauth_consumer_key=”768fe946d252b119746fda82e1599980″, oauth_timestamp=”1316657628″, oauth_nonce=”C2F26CD5C075BA9050AD8EE90644CF29″, oauth_signature_method=”HMAC-SHA1″, oauth_signature=”0fhNGlzpFNAsTme%2FhDfUb5HPB5U%3D”, oauth_callback_url=”http%3A%2F%2Fwww.wackylabs.net%2Foauth%2Ftest”, oauth_version=”1.0″

Note: DO NOT send oauth parameters in both the Authoriszation header and the query string (or body) as Flickr thinks you are sending each parameter twice and will generate a different signature from you (unless you include all the parameters twice when you generate the signature, but that’s just silly).

In the next part I will look at error handling.

OAuth and Flickr – Part 1

Flickr recently announced (well OK, it was back in June) that they would be supporting OAuth 1.0a as the future authentication method for accessing the Flickr API. They say that sometime in 2012 the old authentication token scheme will be phased out.

http://code.flickr.com/blog/2011/06/21/flickr-now-supports-oauth-1-0a/

Now on the surface the authentication method that Flickr had been using was very OAuth ‘like’, but as I soon came to realise they are really very different beasts, mostly because unless you get OAuth exactly right it can be very confusing where you are going wrong.

So I thought I would write these posts to take you through, step-by-step how to get OAuth working with Flickr, and then finally how to use the new functionality in the FlickrNet library.

Flickr OAuth Documentation

The first thing you will probably want to do is have a quick read through the Flickr OAuth documentation. I don’t consider it to be an exhaustive document, hence why I am writing this, but it is a good place to start.

http://www.flickr.com/services/api/auth.oauth.html

Right, are you back? Good.

If you want a more in-depth look of the whole OAuth specification then I recommend this:

http://oauth.net/core/1.0a/

Converting from Old to New?

First, if you are converting from old to new here is a run-down of the new oauth parameters, and what they used to be called:

oauth_consumer_key: This is your API Key. You will still need this key, but you will not need to pass the “api_key” parameter any more as it is now called oauth_consumer_key. If you are not doing authenticated calls then you can still use OAuth to send your API Key to Flickr inside the oauth_consumer_key parameter.

consumer secret: This is your Shared Secret. As with the old mechnanism you never send this value to Flickr, but use it to generate the signature. If you are not doing any authentication then this is not really needed.

http://www.flickr.com/services/oauth/request_token: This is the URL endpoint for requesting a temporary token for performing OAuth authentication. This replaces effectively the “frob” or the “flickr.auth.getFrob” method. Note, previously the frob was a single value, but now the request_token is made up of both a token and a secret.

http://www.flickr.com/services/oauth/authorize: This is the web page you redirect the user to to perform the authorization.

http://www.flickr.com/services/oauth/access_token: And finally this is the URL endpoint that you request your permanent access token and access token secret from.

oauth_token: There are two ‘tokens’ used during the authentication process. The request token is the first one, and is only used during authentication. The access token is returned at the final step of authentication and is used for calling normal Flickr methods.

oauth_token_secret: Both tokens used above have a corresponding secret (so there is a request token secret, and an access token secret). Which token secret you use to sign a call depends on which token you are using. During authentication this will be the request token secret, and afterwards the access token secret.

oauth_timestamp: This is the number of seconds since 1/1/1970, sometimes called the unix epoch. Note, this time should always be calculated using GMT (or UTC) times, not local times. If your timestamp is not a current time (i.e. is more than an hour out) then Flickr will reject your call to the Flickr API.

oauth_nonce: A random series of characters unique to this call to Flickr. If you have two users using the same web page that both make calls to Flickr at the same time then the timestamp will be the same, but the oauth_nonce must be different.

oauth_callback: The callback URL in the Flickr API Keys settings is now ignored, and you sent the callback url every time you call the request_token endpoint. This does mean you can include anything you want in the url, and you can also use the same consumer key for multiple web sites if you so desired. Your 1 query per second limit is on a per key basis though, not on a per website basis, so probably better get different keys for different web sites. If you are not using a callback url then you can use “oob” as your callback url. This will present the user with a web page once they have authenticated and they will have to cut and paste the oauth verifier string into your application. There are ways around this that I will go into in a later part.

oauth_version and oauth_signature_method: The version is always “1.0” and signature method for Flickr is always HMAC-SHA1 (although others are supported by the OAuth spec).

In Part 2 I will take you through a sample authentication process.