views:

813

answers:

1

Hi already wrote this observation and question on this question earlier, but only later noticed that it was an old and "dead" question. As I'd really like some insights from others, I'm reposting it as a new question.

To the question of how to do authentication RESTfully, people generally enthousiastically shout "HTTP Authentication". However, I sorf of doubt whether those people ever tried making a browser-based application (instead of a machine-to-machine web service) with REST. (no offense intended - I just don't think they ever faced the complications)

Problems that I found with using HTTP Authentication on RESTful services that produce HTML pages to be viewed in a browser are:

  • user typically gets an ugly browser-made login box, which is veyr user-unfriendly. you cannot add password retrieval, help boxes, etcetera.
  • logging out or logging in under a different name is a problem - browsers will keep sending authentication information to the site until you close the window
  • timeouts are difficult

A very insightful article that tackles these point by point is here, but this results to a lot of browser-specific javascript hackery, workarounds to workarounds, etcetera. As such, it is also not forward-compatible so will require constant maintenance as new browsers are released. I do not consider that clean and clear design, plus I feel it is a lot of extra work and headache just so that I can enthousiastically show my REST-badge to my friends.

I believe that cookies are the solution. But wait, cookies are evil, aren't they? No they're not, the way cookies are used often is evil. A cookie itself is just a piece of client-side information, just like the HTTP authentication info that the browser would keep track of while you browse. And this piece of client-side information is sent to the server at every request, again just like the HTTP Authentication info would be. Conceptually, the only difference is that the content of this piece of client-side state can be determined by the server as part of its response.

By making sessions a RESTful resource with just the following rules:

  • A session maps a key to a user id (and possibly a last-action-timestamp for timeouts)
  • If a session exists, then that means that the key is valid.
  • Login means POSTing to /sessions, a new key is set as a cookie
  • Logout means DELETEing /sessions/{key} (with overloaded POST, remember, we're a browser and HTML 5 is a long way to go yet)
  • Authentication is done by sending the key as a cookie at every request and checking whether the session exists and is valid

The only difference to HTTP Authentication, now, is that the authentication key is generated by the server and sent to the client who keeps sending it back, instead of the client computing it from the entered credentials.

I feel that this is a sufficient solution that works fine, but I must admit that I'm not enough of a security expert to identify potential holes in this scheme - all I know is that hundreds of non-RESTful web applications use essentially the same login protocol ($_SESSION inphp, HttpSession in j2ee, etc). The cookie header contents is simply used to address a server-side resource, just like an accept-language might be used to access translation resources, etcetera. I feel that it is the same, but maybe others don't? What do you think, guys?

+2  A: 

An interesting question. I'm finishing up a REST API implementation right now - having used mod_rewrite and PHP. It uses HTTP basic auth across HTTPS. So far we're working on a Palm Pre client. The guy developing that client was a little put off at having to keep track of user credentials to submit with each request.

The idea of exposing SESSION as a resource is an interesting one. Including it would still violate strict RESTful principles. Even if you expose SESSION as a resource, you'd still be using the server to keep track of client state. Strict adherence to REST would probably require use of cookies, as that's the client-side persistent memory available to you from the browser. Problem is that leaves you to create a JavaScript (or FLash?) client to manage the HTTP requests client-side if you don't want users interacting with the browser-implemented gathering of HTTP credentials.

One tool I've found helpful is the REST Client for Firefox tool... but I still enter my credentials into the standard browser popup even when I'm using that.

I have to admit to including some hacks in my implementation. If all your doing is using sessions to allow for testing/browsing of the API by potential developers or something I don't think that using session-based authentication is such a big deal. Purists would disagree I'm sure. Really that's what this comes down to... this is essentially an academic argument. In real-life situations you have to do what works.

codemonkey
Hey, thanks for your answer! I do not agree, however, that exposing a session means you keep client state on the server. A session is "the belief that whoever knows some key K is user U", which clearly is a belief held by the server. Sure, it's not very static data as sessions quickly go invalid, but who said server state has to be static? Compare to a RESTful shopping cart system.My biggest worry is, really, that the "having key K means that the server thinks your user U" feels very insecure to me, but I'm not sure how to fix that.
skrebbel
a very interesting point. still, a cornerstone of RESTful programming is that one doesn't ask the server to hold onto client/application scope information. the resource request, "cannot take advantage of any stored context on the server". i actually like this idea of client state as a resource, but i do continue to believe that it's a clear violation of REST principles.
codemonkey