Stuck With OAuth
coinforge
Registered Users Posts: 6 Beginner grinner
I'm working on a new awesome commercial product that is going to feature some smugmug integration, and I figured I'd start at the beginning with this, and get OAuth working.
This is the first time I've had to do OAuth interaction, and I've spent a fair bit of time reading the spec and RFC for OAuth. The spec indicates that if you are using HTTPS for your request, you are permitted to use PLAINTEXT as the oauth_signature_method, but all my attempts to use this tonight have failed. Either I don't understand how to construct a correct PLAINTEXT signature, or the smugmug API is not actually supporting it.
It is my understanding that to create a PLAINTEXT signature I just need to construct a string of (my smugmug api secret) + "&" + (token secret if available), then url encode the whole thing.
What am I doing wrong?
The spec for OAuth is defined here: (section 9.4.1 is what I'm trying to follow)
http://oauth.net/core/1.0a/#anchor21
Thanks!
This is the first time I've had to do OAuth interaction, and I've spent a fair bit of time reading the spec and RFC for OAuth. The spec indicates that if you are using HTTPS for your request, you are permitted to use PLAINTEXT as the oauth_signature_method, but all my attempts to use this tonight have failed. Either I don't understand how to construct a correct PLAINTEXT signature, or the smugmug API is not actually supporting it.
It is my understanding that to create a PLAINTEXT signature I just need to construct a string of (my smugmug api secret) + "&" + (token secret if available), then url encode the whole thing.
What am I doing wrong?
The spec for OAuth is defined here: (section 9.4.1 is what I'm trying to follow)
http://oauth.net/core/1.0a/#anchor21
Thanks!
0
Comments
SmugMug API Developer
My Photos
I was only trying to start the first step of the OAuth authentication process, using smugmug.auth.getRequestToken. The way I am doing this is by using an HTTP POST request to the secure (https) base url of the smugmug api. You can also do this as a GET request, and you don't have to use https, but the signature construction is MUCH simpler if you do.
Since I'm POSTing, I just need to construct some key/value pairs to send along as form variables. They are:
method=smugmug.auth.getRequestToken
oauth_consumer_key={The API key provided by smugmug - you have to request one.}
oauth_nonce={A random string of alphanumeric characters that is unique to EVERY call. I wrote a simple method to produce a random jumble of characters each time I want to POST}
oauth_signature_method=PLAINTEXT - you can choose several signature methods, but PLAINTEXT is by far the simplest. However, it is ONLY available over ssl.
oauth_signature={The API secret provided by smugmug with your key, then an "&" appended to the ned} This is the parameter that I got suck on. The OAuth docs are very specific that all variables MUST be url encoded before they are submitted... so I was passing this signature through a urlencode method before submitting the form. What I didn't realize is that the environment I'm using automatically urlencodes ALL form data, so I was encoding and so was my socket under the hood.
oauth_timestamp={current unix timestamp, the number of seconds since Jan 1, 1970 at midnight}
oauth_version=1.0 - this one is optional, but I was encouraged to use it.
So there you go - for me, the hardest parts to figure out were the nonce and getting the signature right. You can read much, much more all about both of these in the official OAuth documentation here:
Nonce: http://oauth.net/core/1.0a/#nonce
Signature: http://tools.ietf.org/html/rfc5849#section-3.3
More fun reading: http://tools.ietf.org/html/rfc5849#section-3.3
Cheers!
http://www.vanesoftware.com/ismug
uSmug, for grandma!
http://www.vanesoftware.com/usmug
REST has to do with the mechanism you use to communicate with the SmugMug servers. oauth is the mechanism you use to tell the SmugMug api who you are and get permission to do things. The SmugMug docs are not very clear due to how sparse they are, but in essence you can make any webservice call using either the REST, PHP, JSON, or XML-RPC endpoints. An "endpoint" in this instance just means "the URL I post my request to". If you post your request usingthe JSON url, you'll get a JSON response. If you post it using the PHP url, you'll get a serialized php object in response.
I'm using REST as my endpoint, because the response is simple XML that is easy to parse in nearly any language, and I'm not using one of the typical languages for my client side of things.
As to why I'm using oauth instead of a basic call: in short, oauth gives me more power. Most of the API calls have both a "Basic" and an "OAuth" set of arguments. Using OAuth, I don't have to know or store the actual username or password of the smugmug user, and I'm able to have full access to all their stuff in SmugMug because my OAuth keys requested and the user granted that level of access.
So, that's a bit long-winded way of saying: I use OAuth versions of the API calls over the REST interface.
Make sense?
Your post actually addresses where I'm stuck. Using basic REST, I haven't been able to authenticate as the user and get full access. Perhaps your post is telling me that oauth is what I need to get full access. See reference post here.
Do I have that right?
http://www.vanesoftware.com/ismug
uSmug, for grandma!
http://www.vanesoftware.com/usmug
I got the smugmug.auth.getRequestToken working successfully (thanks to coinforge). Now I'm stuck at smugmug.auth.getAccessToken.
getRequestToken's response includes a Token id and Secret. Which one do I pass onto which parameter for getAccessToken?
I tried:
oauth_signature = urlencode(Consumer secret + "&" + Secret)
oauth_token = Token id
I get "invalid/expired token" error.
Edit: original post was way off..
Any advice? Thanks.
http://www.vanesoftware.com/ismug
uSmug, for grandma!
http://www.vanesoftware.com/usmug
http://www.vanesoftware.com/ismug
uSmug, for grandma!
http://www.vanesoftware.com/usmug
the oauth_token is the Token ID that is returned from getRequestToken. The oauth_signature is the harder part, though it looks like you figured it out from the above code - it is the API secret that you originally received from SmugMug, then an "&" symbol, then the secret you received from the getRequestToken call. All of that has to be urlencoded when sent to the server, but be careful that your environment does not transparently encode anything a socket sends (that was my gotcha).
See my next reply about how to get user authorization handled so that you have a valid access token...
Why do you think that you can't redirect the user to a web page? I'm not writing in iOS for my current smugmug project, but I have written about 2 dozen iOS apps over the last year - you can most definitely open a URL in Safari for the user. In fact, there are several ways you can do this (embedded browser in your app, or pass off to the full Safari that is built into the OS - i.e., switch to Safari as the front app).
This makes it very easy to do the user authorization step, but switches away from your application. To get it to gracefully switch back, I have a theory. I've not done this with SmugMug on iOS specifically, but I have done it with other apps: Register a url handler for your smugmug app when it is installed. Then have the redirection URL that smugmug allows you to use send the user right back to your app.
Quoting the OAuth section of the SmugMug api guide: "We don't support the oauth_callback parameter, a static callback can be defined against an API Key by clicking the 'change' link next to the API Key details on the Settings tab of the Control Panel." - in other words, go look at your API Key in your control panel. There is a field there for you to use to define where the user should be sent when the auth is completed. I presume you can send them to something other than an http:// address... so just put in your own url handler there - such as myawesomeapp://somethingcool - then just register myawesomeapp as a protocol handler in iOS for your application.
You can read more about the iOS end of things here:
http://kotikan.com/blog/posts/2011/03/passing-data-between-ios-apps
and here:
https://www.google.com/search?q=CFBundleURLTypes&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
My point of reference at the moment is the Android Smugmug app, which traverses the basic 3-legged oauth process. It loads what seems to be a smugmug.com page to authorize the request token. After I log in, it sends me back to the Android Smugmug app. I'm not sure how that's achieved on that app without the callback_url - perhaps someone from Smugmug who wrote the app can share?
You may be right, coinforge - the only way I could think of to redirect the user back to my App would be your suggestion, the custom url handler.
In any case, while I'm waiting for any one else to chime in, I'll try your approach and report back. Thanks.
http://www.vanesoftware.com/ismug
uSmug, for grandma!
http://www.vanesoftware.com/usmug
http://www.vanesoftware.com/ismug
uSmug, for grandma!
http://www.vanesoftware.com/usmug
http://www.vanesoftware.com/ismug
uSmug, for grandma!
http://www.vanesoftware.com/usmug
After logging in, it says "SmugMug doesn't recognize this application's credentials".
Any help, thanks.
http://www.vanesoftware.com/ismug
uSmug, for grandma!
http://www.vanesoftware.com/usmug
http://www.vanesoftware.com/ismug
uSmug, for grandma!
http://www.vanesoftware.com/usmug