24

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?

Community
  • 1
  • 1
skrebbel
  • 9,841
  • 6
  • 35
  • 34

2 Answers2

4

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 you're 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.

... adding to this on 10/23/2012 ...

The RESTful methodology insistence on making the client keep track of its own state isn't just academic. It has important implications for scalability and the addressability of the exposed resources. When I say this I assume that by client state we are talking about attributes specific to a requesting user which affect the responses issued by the RESTful interface(s). One of REST's strengths is its addressability. When you make its responses in any way dependent on information not passed in the request you start chipping away at that. Just an afterthought... 3 years later, lol.

codemonkey
  • 2,661
  • 2
  • 24
  • 34
  • 1
    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 Jul 17 '09 at 13:02
  • 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 Jul 20 '09 at 17:35
  • I have never quite understood why the RESTful spec is so adamant about statelessness, even when it comes to user auth. Perhaphs you can shed some light. In fact, the only instance in which I will be "violating" is is user auth becuse I plan to run my API out of Glassfish and keep track of user sessions. If a session is not open, the client gets a corresponding return code and then he can submit credentials via digest auth. once he is authenticated, he is good to go within the session until it expires, i.e. no reauthentication upon every REST request. I think this is a reasonable compromise – amphibient Oct 23 '12 at 17:29
  • I am 100% onboard with the one-URI=1-object paradigm in REST and the rest of stateless principles. but requiring reauthentication every request is a bit unreasonable, IMO – amphibient Oct 23 '12 at 17:30
1

I know this is a bit of an old question, but I think a lot of the questions here have been addressed in different areas. In particular, I think the OAuth 2.0 Protocol has been considering a lot of these questions; I don't feel authoritative enough to provide a summary of their answers here, but the linked site has a lot of differing use cases called out explicitly, which seems very useful for this question, even if the full OAuth 2.0 isn't really necessary here.

Paul Sonier
  • 38,903
  • 3
  • 77
  • 117