OAuth and Flickr – Part 2

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.

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.

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.

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.

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):

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.

Share this:

71 Replies to “OAuth and Flickr – Part 2”

Hi Sam,
thank you for your effords done for this article.
how do you get the nonce C2F26CD5C075BA9050AD8EE90644CF29? Could you put some code snippets in this article, so we do not have to code it for ourselves. Can we finde somewhere an algorithm coded in some programming language, no matter which.
What kind of oauth_callback is used if you have a desktop application like Gucki?
Gucki ist written in C++ and .NET. I would like to have a very simple way to send pictures to Flickr which needs no instalation. I would prefere simple C. So that it can be used by many apps. If one has a library or dll it ist not so flexible. It would also be nice for the use with GIMP. But whith no complex pattern matching an other things. I also do not like Pyton or Perl or PHP apps. They all require to much effort for instalation.
Thank you for helping, Moni.

Hi, thanks for the walk through. Very clear. I am trying to get a actionscript application to authenticate with Flickr using oauth. I appreciate that you may not have experience in this area but the principles are the same I guess. Anyhow, I am using your base string and key to test the Hash algorithm used in actionscript as follows:-

Hey that was fast, thank you. I replaced the base url in the previous comment with a cut’n’paste from above.
ie I used
var bs:String=”GET&http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Fwww.wackylabs.net%252Foauth%252Ftest%26oauth_consumer_key%3D768fe946d252b119746fda82e1599980%26oauth_nonce%3DC2F26CD5C075BA9050AD8EE90644CF29%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1316657628%26oauth_version%3D1.0

the key passed into the hashing algorithm is the same as before ie
oauth_signature = HMAC.hash(’1a3c208e172d3edc&’,bs, SHA1);

First thing to say is thank you for your time and effort.
For those interested. I chased down the com.hurlant.crypto.Crypt and went to the demo at http://crypto.hurlant.com/demo/
I set the encryption to HMAC and added your key to the key format: input box as text

I then added your base url to the input format box and clicked computHmac button.

Lo and behold your signature popped put correctly.
You are correct the in-built HMAC encryption functions do not generate the correct signature.
Once again thank you
John.

Hi Sam,
I am working out when to encode the data in actionscript. I notice in the base_url you supply to generate the signature you have a string ..
Base String = “GET&http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token&
oauth_callback%3Dhttp%253A%252F%252Fwww.wackylabs.net%252F……

As an observation, should the & after …%2Frequest_token be a question mark ?

Hi, Finally managed to get the Request token from Flickr. I understand from the Flickr documentation that if I need to view private photos I now need to exchange the request token for an access token . I send to flickr http://www.flickr.com/services/oauth/authorize?oauth_token=… with all relevant request parameters. Flickr responds with the authorisation page and I click the authorise this app button. Flickr responds again by saying that I am authorised and displays three -dash- seperated numbers and asks that I add this to my app. The actual documentation doesn’t mention this response instead it indicates I should expect a simple string … ie .
“Flickr returns a response similar to the following:

Hi Sam, Just read my previous post and if it appears unpolite/testy I apologize. You have been a great help in this.
I’ve already tried adding the ‘three-dash’ number as the verifier but still no joy.
Two further questions tho’. The verifier in the documentation is a 16 figure digit, so I was uncertain this actually was the oauth_verifier. Is the documentation incorrect ?
Also, do I include the dashes?
The documentation says I should use :http://www.flickr.com/services/oauth/access_token
?oauth_nonce=37026218
&oauth_timestamp=1305586309
&oauth_verifier=5d1b96a26b494074
&oauth_consumer_key=653e7a6ecc1d528c516cc8f92cf98611
&oauth_signature_method=HMAC-SHA1
&oauth_version=1.0
&oauth_token=72157626737672178-022bbd2f4c2f3432
&oauth_signature=UD9TGXzrvLIb0Ar5ynqvzatM58U%3D

If I take the string returned in the error message and generate a signature from it I get
EXACTLY the same signature…so why the error ? Unless they use a different encryption algorthm to the one used in the request token

If you base string matches exactly the debug_sbs then you either have the signature secret wrong (consumer secret + “&” + request token secret) or you aren’t adding the signature to the final URL correctly (not urlencoded perhaps?)

If you base string matches exactly the debug_sbs
This is crucial. I nearly ripped all my hair out trying to figure out why some methods worked fine for me while others didn’t. It turns out that I was sending the requests to http://flickr.com… but when I got the debug_sbs parameter back it the base string had www added to it (http://www.flickr.com…). When I sent the same request to http://www.flickr.com… it started working fine on all methods.

Hi Sam,
I want to paginate images in groups of 20. When I call flickr.photosets.getPhotos I need to pass it a page number which will be created dynamically . Do I have to go through all the process of creating a list of parameters, and generate a new signature everytime I call for the next page ?

Ok Sam engaged brain.. Download all images and store the links in a collection. Show first 20. When a’Next page’ button is clicked simply show the next 20…only make a fresh call once the limit…500 has been reached. Any other way of achieving the same thing ?

Sam, it says somewhere in the documentation that ALL calls to the api should be signed. So I have created a list of all my photosets, 3 in this case and placed them in a dropdownlist type component. When I change my selection in this box I want to show only those photos in that photoset. As the photoset id is different from the previous one do I need to go through the process of creating a new signature ?

Hi Sam,
I am a new programmer in oauth
I had project to upload Image from android cam or video to my flickr
I start to make my project using oauth I only had the following information
public static final String CALLBACK_SCHEME =”x-oauthflow”;// “flickrj-android-sample-oauth”; //$NON-NLS-1$
public static final String PREFS_NAME = “Accinflickrpref”;
public static final String KEY_OAUTH_TOKEN = “*************887835243-4b438e765e498fee”;
public static final String KEY_TOKEN_SECRET = “**********84cc7845”;
public static final String KEY_USER_NAME = “AccidentApp”;
public static final String KEY_USER_ID = “[email protected]”;
private static final String API_KEY = “3*****************bd7d97395ea9b6777”;
public static final String API_SEC = “f0*************81caf”;

my code give me that the outh is ok
but now I cant connect all that to upload photo
I dont know how exactly to start from oauth
you take about oauth header but dont know how to get the rest of other information

I want to use javascript to authenticate to Flcikr but i have some issues …

Is JSONP supported in the Flickr OAuth API ?

I tried to use the OAuth API but i can not get response in JSONP :-(
For exemple when i call “http://www.flickr.com/services/oauth/request_token” with good parameters (plus “format=json”), i do not receive a response in json format but “oauth_callback_confirmed=true
&oauth_token=72157626737672178-022bbd2f4c2f3432
&oauth_token_secret=fccb68c4e6103197”

Due to crossdomain, I can not receive anything other than a response in format json …
if the whole process of identifying an user cannot be done with JSONP responses, i can not authenticate to flickr with javascript ?

Yes, both are same. Baseurl is : GET&http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Fwww.techaviator.com%252Fshiv%252Fflickr%252Fcallback.php%26oauth_consumer_key%3D653e7a6ecc1d528c516cc8f92cf98611%26oauth_nonce%3Decb4d67cde0d2a519b233c770525289b%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1331732253%26oauth_version%3D1.0

I have to say I’m stumped. If the base strings are identical then it is usually either the signature key that is wrong, the way the signature is generated, or the way it is appended to the URL. All of these look fine based on the code you have posted above.

How on earth can we tell what mistake you are making when we know nothing about what you are doing. Yes, the order of the parameters is critical when generating the signature, as highlighted above if you actually read the article.

i am using digg.com api. i think it’s almost the same. can u help me for the same? I have successfully received the request token but i am receiving invalid signature in case of access token. should i post the code for your reference?

The order for OAuth, whether Flickr or elsewhere will always be sorted alphabetically when generating the signature. Also you need to make sure when creating the key for the signature that you include both the consumer secret and the request token secret.

As you stated that “Also you need to make sure when creating the key for the signature that you include both the consumer secret and the request token secret”.you mean to say this for access token. right?

Please let me know whether following order is correct or not for getting access token.

i have received the oauth_token and oauth_token_secret from request token URL now i have to receive the access token for which i am getting the invalid signature. Following is the code for thathttp://pastebin.com/9Gb0Ceat

The links don’t work anymore, but no, I don’t have any idea why 3 or 4 times out of 10 it doesn’t work. My only guess would be that there is something you are doing that only fails under certain circumstances, but what they are I don’t know.

Thank you Sam for your posts in this blog!
Now I finished code for auth and I have
{“fullname”:”Nikolay%20Zavada”,”oauth_token”:”721576ww220597242-05cf8b3960f1fa95″,”oauth_token_secret”:”a0f43f55dda34563″,”user_nsid”:”22967268%40N03″,”username”:”nikolay.zavada”}

i am using OAUTH for flicker and i am going to upload photo’s to my website

I have read your blog and i am following the procedure

I am getting the request token and i am sending it for authorization,here the flickr
is redirection to the url where i am getting request token and verifier again
I am unable to get request _token_secret which is required for getting access token
can you please tel me how i can get it

Have you checked your code for requesting a permanent Authentication token in the last month?

I have found the following:

1) All permanent Auth Token/Secrets I have requested in the last 30 days remain valid for only 24 hours – even though the Authorization page on Flickr (http://www.flickr.com/services/oauth/authorize) indicates they will be valid until deleted.

2) Older tokens that I created more than 30 days ago have not expired

3) My code to request a permanent Authorization Token has not changed.

Please ignore that last request. I had a senior moment. My script was generating the Access Token/Secret correctly but displaying the Request Token/Secret instead – hence the expiry after 24 hours.

Around 3 months ago I had updated the code when I had to swap server and changed from using the PECL OAuth library to a different OAuth.php script. During that change I introduced the bug of displaying the wrong token. Anyway, after lots of head scratching, and finally, a light bulb moment, Thunderbirds are Go

Hey Sam,
First thank you for the eplanation that u have provided… I am facing a problem with timestamp…I’m using php for my app… I’m from India so the timestamp is not UTC… I tried using gmdate() and many more functions in php… still i’m getting the error timestamp_refused… Can u suggest some ways in which I can genarate utc format timestamp.

Without wanting to be rude, basically I wouldn’t. To get it working JavaScript you would need to include your api key and shared secret in plain text, and I view this as an unacceptable security risk. Unauthenticated calls to Flickr are fine, but for that you don’t need OAuth.

Hi Sam!Thank you for the great issue.Would you please write a post to show how to send HTTP headers with curl? And I’ve worked in the tumblr API,and find it’s similar to Fliker’s API. Here is the code I found: