Yesterday there has been a popular post on Hacker News about Designing Secure REST API ** without OAuth**. I don’t agree that OAuth is unsuitable and I’ll introduce my way shortly. This post is intented to be a reply on this topic. In our new startup (ollaa.com), we (3 undergrad co-founders) are basically developing a mobile social network that has iOS/Android clients communicating the server via a REST API. We also looked at how we can provide a secure authentication to our API.
Earlier in our development days, we developed our own proprietary authentication method. It basically should not make us store passwords on the clients and should be extendible for 3rd party apps (who should not know user passwords).
Naively, we were just passing
/api/someEndpoint?username=xxx&passsword=xxx
as URL parameters. But later on we realized that will cause serious issues:
-
You can’t just transmit credentials over a non-secure connection. Your API endpoints SHOULD be accessible through SSL (https). Otherwise, you’ll end up having man-in-the-middle attacks.
-
It’s not convenient to pass username-password on all API requests.
-
We can’t extend this authentication schema to 3rd party apps built on top of our API. Basically we can’t let them know passwords of our users. Later on we decided to use OAuth 2.0. (I won’t be telling how OAuth2 works here.)
-
-
Better than OAuth 1.0 (name says so!)
-
No need for HMAC-SHA* encryption and all that handshaking crap
-
No need for all that timestamp, nonce crap.
-
No need to sign every request with encrypted token.
-
Damn easy to implement both server-side and client-side.
-
Everybody uses it (Facebook, Foursquare, Instagram …), but Twitter.
Why not OAuth2?:
- Remember that page that user is asked for permission to allow app to access his/her data? We definitely should NOT show users such a confusing page on our official iOS/Android apps. It kills simplicity. So how we solved this problem of authenticating users from our official mobile clients?
Simple. In our oauth2_clients database, we indicated that our iOS/Android apps are “official” with a flag. Then while issuing “access_token"s, we allowed our official clients to directly do that without redirecting our users to allow/deny page.
Here’s how standard oauth2 access_token endpoint looks like:
/oauth2/access_token?client_id=XXX&grant_type=**authorization_code**&code=XXXX
Here’s how we changed it:/oauth2/access_token?client_id=XXX&grant_type=**user_credentials**&**username**=XXX&**password**=XXX
Done.
Our iOS/Android apps can authenticate over OAuth2, just like other 3rd party apps will do in the future. Only difference is that our official clients won’t need to navigate users to the authorization page.
OAuth2 proposal do not mention any other usage of “grant_type” parameter, therefore I think it can be extended in that way.
At the end, you can have
-
support for 3rd party OAuth consumer clients in the future with this small change and it costs just several lines of extra code
- (3rd parties will not be allowed to use
grant_type=user_credentials)
- (3rd parties will not be allowed to use
-
a secure API runs over SSL/TLS protocol
-
a standard authentication schema that won’t made you think of inventing your own. (At ollaa.com, we do such funny hacks everyday. Don’t forget to leave your e-mail for beta invitation.)
Leave your thoughts