
Every day it seems like I see another tweet or plea for help from a developer flailing about trying to implement oAuth in their desktop or mobile application. This is because oAuth is probably the least user friendly technology I have encountered in my decade of software development. As frustrating as it is useless, I cringe every time I need to come near it. For the busy, here are the bullet points of my upcoming rant:
- oAuth doesn’t protect the end user’s password
- oAuth is a horrendous user experience
- oAuth is not impossible, but a pain to implement
- Using common sense in your web service API design, all the goals of oAuth can be realized
While oAuth is reasonably easy to implement in a browser-based application, it remains incredibly unwieldy for desktop, mobile, or any other type of client. With a bit of determination, the libraries exist to do oAuth in your client app today, the JavaScript version of which works in Titanium with a bit of massaging. For Titanium Mobile, there’s a welcome attempt from a community member to generalize the process out into a JavaScript library, which is so far looking promising, if a little rough around the edges. So without a doubt, there are many, many people who have successfully implemented oAuth in many different contexts, so clearly it is possible. It is also possible for me to swim from Saint Paul to Minneapolis in the Mississippi river in early December wearing a Speedo and a rakish grin, but that doesn’t mean it’s a good idea.
Here’s why oAuth is ridiculous, and should be banished from the face of the Earth. It should be said that these arguments largely pertain to non-browser web service clients:
oAuth does not protect the user’s password
The biggest fallacy of oAuth is that it prevents an end user’s password for Service A being retained by Service B, who uses Service A on behalf of the end user. By taking the end user to a login screen branded by Service A, the user is made to believe they are giving their password to trusted Service A (which most of the time is the case). However, if I am the developer of Service B, and I have a malicious intent to grab the user’s password, I have any number of ways to intercept the password being entered. Or maybe I just fool the user with a well-decorated login screen which mimics the look and feel of Service A.
I call shenanigans on this most ‘useful’ feature of oAuth - it’s no more secure than giving your Service A username and password directly to Service B.
oAuth is an awful user experience
I shouldn’t have to call out that opening up a random browser window, removing the user from your experience, is hardly an ergonomic means of authenticating users. Anyone who has used a Facebook-connected desktop app knows how weird the boxy blue CSS of Facebook looks inside an application that is neither blue, nor boxy. This is a minor gripe, but from a UX perspective I am diametrically opposed to disrupting the user’s interaction with my application by kicking them out to a browser window, embedded or not. Especially since, as noted earlier, it does not enhance their security.
oAuth is painful to implement
Yes, there are many client libraries out there for consuming oAuth services (so too are there for SOAP web services, maybe the next most reviled technology on my list). But there are just as many developers who struggle to implement these libraries in different languages and different runtime environments. oAuth is a weird abstraction layer dependent on a bizarre song and dance of hashing and string concatenation, none of which is ultimately necessary if you make different choices in your web service API design. And I am generally distrustful of any web service API that requires a sophisticated client library to even use (yes SOAP, again I am looking at you).
The goals of oAuth can be achieved differently
Maybe I am missing something, but as far as I can tell there are a few named benefits of oAuth from the perspective of the oAuth provider:
- Do not divulge username/password combos to third parties
- Do not require (or allow) the use of username/password combinations on every request
- Retain the ability to revoke the permission of a third party application to act on a user’s behalf
The first problem is essentially unavoidable for the reasons stated in the first bullet point - if a third party is going to ask for a username and password combination, they have the ability to grab and retain it if they act unethically. What you as the web service provider can do is design your web service API such that a username/password is exchanged for a token, which may have an expiration date and can be revoked if needed. In this case, the third party has no ethical reason to retain a username and password, which is the best you can hope for. A reasonable web service API will:
- Use SSL to protect the contents of a request and response
- Exchange a password for a token that can be revoked by the service provider or the end user
- Require the use of a token for authenticated requests, not a username/password combo
- Potentially, use an API key to have an understanding of who is using your API and why, and retain the ability to shut them down if they cause problems.
None of this requires the two or three legged oAuth BS that serves as a source of consternation for so many developers. Am I missing something? Taking crazy pills? If so, please set me straight in the comments. Otherwise, join with me in rising up against needless complexity in web service APIs.