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.

71 Replies to “OAuth and Flickr – Part 2”

  1. 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.

  2. The nonce can be any unique string. Some people use a unique timestamp, others use a random number generator. In this instance I used the .Net Guid class to generate a unique GUID.

    I cover the callback url a little in part 1, and will cover it more in a future part (possibly part 3, or it might get squeezed into part 4).

  3. 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:-

    var bs:String=”GET&http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Fwww.example.com%26oauth_consumer_key%3D653e7a6ecc1d528c516cc8f92cf98611%26oauth_nonce%3D95613465%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1305586162%26oauth_version%3D1.0″;

    in actionscript the hash is generated as so :-

    oauth_signature = HMAC.hash(‘1a3c208e172d3edc&’,bs, SHA1);

    I don’t get the same value that you do, ie ‘0fhNGlzpFNAsTme/hDfUb5HPB5U=’

    Given that its the same base url and key I would expect the same signature. The only thing I can think of is either the hashing algorithm is different or the inputs are wrong.

    Am I passing the correct inputs ?

  4. 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);

    Same problem, different signature….driving me up the Great End !

  5. Here’s another clue…the output from your hash method gives a string of a different length to mine..
    d1f84d1a5ce914d02c4e67bf8437d46f91cf0795
    0fhNGlzpFNAsTme/hDfUb5HPB5U=

    The hash method I used has 2 methods:-
    HMAC.hash(‘1a3c208e172d3edc&’,bs, SHA1);
    HMAC.hash(secret:String, message:String, algorithm:Object=null):String

    and
    HMAC.hashBytes(….,bs, SHA1);
    HMAC.hashBytes(secret:ByteArray, message:ByteArray, algorithm:Object=null):String

    (The documentation for these methods is all arsy-versy as well)

    I wonder should I convert my base string and key to a byteArray first ?

  6. Both of those return a string, which I’m not sure is right. What you want is it to return a byte array and then base64 encode the byte array.

    Most implementations around the net appear to use com.hurlant.crypto.Crypt. This seems to indicate that the built in HMAC implementation is not capable of doing this correctly.

  7. 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.

  8. 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 ?

    I dont usually code for the web…

  9. 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:

    fullname=Jamal%20Fanaian
    &oauth_token=72157626318069415-087bfc7b5816092c
    &oauth_token_secret=a202d1f853ec69de
    &user_nsid=21207597%40N07
    &username=jamalfanaian”

    Have you come across this ? What is supposed to happen now ? Anybody ?

  10. Once you have the number with three-dashes that is the oauth_verifier. You then send that, along with the request token to the access_token URL.

  11. 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

    Here’s my version:
    http://www.flickr.com/services/oauth/access_token
    &oauth_consumer_key=be211209a5054354064bfec8fb0cada6
    &oauth_nonce=64631345
    &oauth_signature_method=HMAC-SHA1
    &oauth_timestamp=1327398023
    &oauth_token=72157629009648509-80723eb271cd2bc6
    &oauth_verifier=873-728-592
    &oauth_version=1.0
    &oauth_signature=41kdqcqpqhl2f2IM/kxKB//0Gr8=
    &perms=write

    The response is a message from Flickr stating ‘You don’t have permission to access this URL on this server’ .

    Does the ‘perms=write’ have to be part of the signature ?

  12. This feels like nailing jelly to a wall…
    Anyway I send the appropriate string:
    GET
    &http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Faccess_token
    &oauth_consumer_key%3Dbe211209a5054354064bfec8fb0cada6
    &oauth_nonce%3D35197928
    &oauth_signature_method%3DHMAC-SHA1
    &oauth_timestamp%3D1327421466
    &oauth_token%3D72157629013334217-4a83d8a75d6764d1
    &oauth_verifier%3D755-955-488
    &oauth_version%3D1.0

    This generates a signature of 6FDW75A0amJrpnlR+85GkmnmTCg=

    I get an error back of

    oauth_problem=signature_invalid&debug_sbs=GET&http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Faccess_token&oauth_consumer_key%3Dbe211209a5054354064bfec8fb0cada6%26oauth_nonce%3D35197928%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1327421466%26oauth_token%3D72157629013334217-4a83d8a75d6764d1%26oauth_verifier%3D755-955-488%26oauth_version%3D1.0

    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

    I’m loosing the will to live …

  13. 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?)

    1. 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.

      Thanks Sam!

  14. Sam, you are a gem… came in this morning and reread your blog. I noticed the phrase,

    ‘As this is the first stage you have neither, so your token secret is simply an empty string.’

    Added the oauth_token_secret and voila, the expected string is returned.

    I guess I should create a blog to save others from the pain…

    Many thanks, you don’t know how relieved I am :-).

  15. 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 ?

  16. 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 ?

  17. No, that’s probably the simplest. Obviously if you wrap the call to getPhotos in a function and pass in the page number and per page number then it shouldn’t be too hard to do it either way really.

  18. 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 ?

  19. 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 = “74488019@N02”;
    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

    another question is oauth work perfect with android ?

    <code deleted by sam>

    1. Thank you for replay
      I need really some one to help me on this
      can you know any one how work with java android on upload photos from camera to website and flickr ???
      I am able to pay for that

      thank you

  20. Hello,

    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”

    Have you got an idea ?

    1. The response format is fixed by the OAuth specification, and cannot be changed by appending “format=?” onto the request. You’ll just have to use JavaScript to parse the string that is returned.

      1. 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 ?

        1. Ah yes, I hadn’t considered that as an issue. I’m afraid it is very likely you won’t be able to do OAuth in javascript then.

          You should raise this on the Flickr-API mailing list.

  21. Hi Sam,

    I had followed all the steps with your credentials and got the signature value

    Signature = “0fhNGlzpFNAsTme/hDfUb5HPB5U=”

    I am having one doubt in the final request url

    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=cFIwso%2F%2Bl%2FgScTN%2FE544B%2FnU07Q%3D”

    I am not getting oauth_signature value “cFIwso%2F%2Bl%2FgScTN%2FE544B%2FnU07Q%3D” after encoding “0fhNGlzpFNAsTme/hDfUb5HPB5U=”

    In php i’m using urlencode() function to encode all the parameters.

    Can you please explain it.

  22. Thanks Sam. Can you please do me a favour!! I am trying to implement API from last 2-3 days. I have done everything carefully but still getting invalid signature error :(. Following is my code.

    mt = microtime();
    $rand = mt_rand();
    $oauth_nonce=md5($mt . $rand);

    $request_token_url = “http://www.flickr.com/services/oauth/request_token”;
    $nonce = $oauth_nonce;
    $timestamp = gmdate(‘U’);
    $cc_key = “653e7a6ecc1d528c516cc8f92cf98611”;
    $cc_secret = “996a72540245c367”;
    $sig_method = “HMAC-SHA1”;
    $oversion = “1.0”;
    $callbackURL = “http://www.techaviator.com/shiv/flickr/callback.php”;

    $basestring = “oauth_callback=”.urlencode($callbackURL).”&oauth_consumer_key=”.$cc_key.”&oauth_nonce=”.$nonce.”&oauth_signature_method=”.$sig_method.”&oauth_timestamp=”.$timestamp.”&oauth_version=”.$oversion;

    $basestring = “GET&”.urlencode($request_token_url).”&”.urlencode($basestring);

    $hashkey = $cc_secret.”&”;
    $oauth_signature = base64_encode(hash_hmac(‘sha1’, $basestring, $hashkey, true));

    $fields = array(
    ‘oauth_nonce’=>$nonce,
    ‘oauth_timestamp’=>$timestamp,
    ‘oauth_consumer_key’=>$cc_key,
    ‘oauth_signature_method’=>$sig_method,
    ‘oauth_version’=>$oversion,
    ‘oauth_signature’=>$oauth_signature,
    ‘oauth_callback’=>$callbackURL
    );

    $fields_string = “”;
    foreach($fields as $key=>$value) {
    $fields_string .= “$key=”.urlencode($value).”&”;
    }
    $fields_string = rtrim($fields_string,’&’);
    $url = $request_token_url.”?”.$fields_string;

    and at the end url is like :

    http://www.flickr.com/services/oauth/request_token?oauth_nonce=ecb4d67cde0d2a519b233c770525289b&oauth_timestamp=1331732253&oauth_consumer_key=653e7a6ecc1d528c516cc8f92cf98611&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_signature=4FxNRXjPDOwLaOUKt8sget0kuIw%3D&oauth_callback=http%3A%2F%2Fwww.techaviator.com%2Fshiv%2Fflickr%2Fcallback.php

    getting the following error :

    oauth_problem=signature_invalid&debug_sbs=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

  23. 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

  24. 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.

    1. Encode the secret? They should only contain letters and numbers and shouldn’t need encoding (e.g. “a0582531c098d3df”). At least this is true for Flickr, but may not be true for other services.

  25. Hi sam i am getting invalid signature. Please let me know what mistake i am comitting. is there any order of parameters for it which matters

    1. 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.

      1. hi sam,

        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?

      2. yes i have read what you have written . but you have written it for flickr. i am working on digg.com api. Please help me to know how should i find the order for access token

        Regards
        Gaurav

        1. 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.

          1. 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.

            oauth_callback
            oauth_consumer_key
            oauth_nonce
            oauth_secret_token
            oauth_signature_method
            oauth_timestamp
            oauth_token
            oauth_verifier
            oauth_version
            oauth_signature

  26. The ordering only applies when generating the signature, not when calling the url, so you wouldn’t have oauth_signature.

    When calling access_token you are generating a signature using the consumer secret and the request token secret – you don’t have the access token till after this.

      1. Yes. Aside from that the order looks fine.

        If you are still having issues then I would recommend posting your code somewhere public (like pastebin) and providing a link.

          1. You need to use the request token secret as part of the key when calculating the signature for access_token call.

            Could I recommend you consider using Flickr4Java rather than rolling your own, as they have already done the hard work in getting all of this right.

    1. 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.

      1. 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”}

        But when I try do something like this

        $request_url = “http://api.flickr.com/services/rest/”;
        $api_key = “676d28f0d2ae990730a3fbc12c252a8b”;
        $secret = “36b056c5d0626fef”;
        $user_id = “22967268%40N03”;
        $method = “flickr.photos.search”;
        $format = “rest”;
        $auth_token = “721576ww220597242-05cf8b3960f1fa95”;
        $oauth_token_secret = “a0f43f55dda34563″;

        $api_sig = md5($secret.”api_key”.$api_key.”auth_token”.$auth_token.”user_id”.$user_id.”format”.$format.”method”.$method);

        $url = $request_url.”?method=”.$method.”&api_key=”.$api_key.”&user_id=”.$user_id.”&format=”.$format.”&auth_token=”.$auth_token.”&api_sig=”.$api_sig;
        header(“Location: “.$url);

        I have error 98 “Invalid auth token”. I think that I choose wrong way. Please help me :)

  27. Hi Sam,

    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

  28. Hi Sam,

    Thanks for you example.

    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.

    Do you have any suggestions as to why the Access Token are expiring?

    Thanks

    1. The only time I have seen this behaviour is if you are using the API key from the API Explorer, rather than your own API key. Auth token’s do not, and never have in my experience expired.

      1. Hi Sam,

        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

  29. Hi Sam,

    Thanks for your answer.

    I have still been testing this more extensively.

    Any new “permanent” authentication token only works for 24 hours. But when I test the token at http://www.flickr.com/services/api/explore/flickr.auth.oauth.checkToken I get the dreaded: err code=”98″ msg=”Invalid token”

    So the token works for 24 hours even through the API explorer indicates it is invalid. How bizarre is that?

    Do your Auth Token’s validate at http://www.flickr.com/services/api/explore/flickr.auth.oauth.checkToken

  30. 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.

    1. 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.

      1. You make a good point. The built in functionality for encoding strings is pretty handy too..

        You probably could do this in JS with some libraries included, of course HMAC SHA1 hashing, plus the UTF8 string conversion.

  31. 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:


    $value) {
    if (strpos($key, "oauth") !== false) {
    $oauth_header []= $key ."=".$value;
    }
    }
    $oauth_header = "OAuth ". implode(",", $oauth_header);
    $headers["Authorization"] = $oauth_header;
    }

    function oauth_sig($method, $uri, $params) {

    $parts []= $method;
    $parts []= rawurlencode($uri);

    $iparams = array();
    ksort($params);
    foreach($params as $key => $data) {
    if(is_array($data)) {
    $count = 0;
    foreach($data as $val) {
    $n = $key . "[". $count . "]";
    $iparams []= $n . "=" . rawurlencode($val);
    $count++;
    }
    } else {
    $iparams[]= rawurlencode($key) . "=" .rawurlencode($data);
    }
    }
    $parts []= rawurlencode(implode("&", $iparams));
    $sig = implode("&", $parts);
    return base64_encode(hash_hmac('sha1', $sig, CONSUMER_SECRET."&". OAUTH_SECRET, true));
    }

    $headers = array("Host" => "http://api.tumblr.com/", "Content-type" => "application/x-www-form-urlencoded", "Expect" => "");
    $params = array("data" => array(file_get_contents("/path/to/file"), file_get_contents("/path/to/file")),
    "type" => "photo");

    $blogname = "testing.tumblr.com";
    oauth_gen("POST", "http://api.tumblr.com/v2/blog/$blogname/post", $params, $headers);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_USERAGENT, "PHP Uploader Tumblr v1.0");
    curl_setopt($ch, CURLOPT_URL, "http://api.tumblr.com/v2/blog/$blogname/post");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "Authorization: " . $headers['Authorization'],
    "Content-type: " . $headers["Content-type"],
    "Expect: ")
    );

    $params = http_build_query($params);

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);

    $response = curl_exec($ch);
    print $response;
    ?>

    I’m looking forward to receiving your reply :D

Leave a Reply to Alex Wakeman (@theworldmovesme) Cancel reply

Your email address will not be published. Required fields are marked *