belfasttim, I'm struggling with the same thing right now. I have a RESTful API with access to sensitive (but not critical) data, and I want to limit access both horizontally and vertically, and I want it to be reasonably secure.
vertical access = which methods a user is allowed to access, what "kind" of data are they permitted to GET/POST/PUT/DELETE. Like, does the app (or the user) have admin privileges, write permissions, etc.
horizontal access = which datums are they permitted to interact with? Perhaps they can POST to their own data, GET from their friends, and if they try to see or molest anyone else's info they get the big 403 status slap.
The strategy I'm using is to issue a dev token and secret string, then ask for a hash of those along with each request. That covers the vertical access control, defining what functions the app can access. But then I want to know the context of the which user is using the app which accesses the API, so I also need a second identifier and hash for that.
There are two pieces of information that are secret, never sent in requests to the API. They are the developer's secret token, and the user's password. Both of these are salted up and hashed into an MD5
1) a microtime(). This is merely an incrementing, usually-unique number
2) a dev token. This gives the requester permission to use the API
3) a hash, which is MD5($microtime . $devtoken . $secret)
4) a userid
5) a userhash, which is MD5($microtime . $userid . $userpassword)
So a complete request looks like (in GET)
When I receive a request to the API, the first thing I do is look up the $secret associated with that $devtoken. Then I check if MD5($microtime . $devtoken . $secret) == $hash. If it matches, then I know the developer token is valid and I can check permissions, do a little request throttling, vertical access control.
Then I check if MD5($microtime . $userid . $userpassword) == $userhash.
This whole thing is a little half-baked, and still in development.
The issues are:
1) I don't want to store user's passwords as plain text in my db, so I can't likely look them up to verify the $userhash
2) I'm not particularly keen on developers being able to write applications that collect login credentials. It's too phishy.
3) I'm currently not verifying that $microtime is unique, or incremental. Not sure that I want to, since it could spawn race conditions
So now I'm looking into something a little more complex, like setting up a session server, and issuing session tokens to the requesting app. Sessions that expire. Sessions you can only get if you come to http://example.com, fill out my form, then get redirected back to the app's landing URL with the session token attached.
I've been looking closely at how facebook does theirs. It is complicated.
Why is there no canonical according-to-hoyle step by step built-in solution for this? What is this, 2007? C'mon people, we need an open source API platform I can snap together like LEGO.
I'm interested in chatting up anyone who has built a solid XML/JSON hybrid API on LAMP, so I can avoid doing it wrong several times and wasting my precious life. Learning the hard way is for losers hahahaha.