Question

I wrote a RESTful servlet, and the UI developer wants to save the logged-in state on the server.

He made this strange claim: "I haven't encountered a production REST implementation that is pure REST. The ones I've seen all have had the server maintain a session."

I find this difficult to accept. First there's the technicality that there are plenty of plain HTTP pages out there, all purely RESTful. Second, yes, there are non-RESTful implementations labeled RESTful, just like there's brass labeled "gold". Third, just because everyone else jumps off a bridge doesn't mean I should.

Background: It's a JavaScript Ajax web application using HTTPS and Basic authentication. To avoid the usual (uncustomizeable) browser login popup box, the application shows a login screen with the product logo and text boxes for name and password. The name and password are stored in the document and sent in the Authorization header for each request. If you refresh the page, the name and password are lost and the user must type them in again. That's considered a bug; the UI developer wants to be able to press the refresh button without giving the password again.

So the developer wants to use a cookie or a JSP session. Abby, is it true that in the end every REST implementation maintains application state on the server? Or is there a way I can solve this problem and still maintain my RESTful purity?

Was it helpful?

Solution

I think that for practical reasons (mainly browsable abilities) you need to distinguish between application state and authentication state. I can't think of any authentication mechanism that doesn't retain some form of state on the server side.

What really matters is how decoupled it is from the application. For example, HTTP Digest retains some form of state on the server, but this is clearly abstracted away as part of the normal WWW-Authenticate and Authorization header negotiation. Because most browsers support it natively, this is orthogonal to the application and as such doesn't break the statelessness principle of REST.

Nowadays, because users have some aesthetic expectations that HTTP Basic/Digest authentication don't meet in the browsers, websites tend to use form-based authentication and subsequently cookies. To be fair it's more than just the way it looks, it also a matter of usability (e.g. "forgotten your password" information, although that could be in the body of a 401 response) and security. Browsers don't let you log off from Basic/Digest/Certificate authentication easily, unless it's done entirely in Ajax within a single page, as you've mentioned, and that can help CSRFs.

I think cookies are acceptable for authentication, but make sure you don't store application-related variables in the session.

You can read some of Roy Fielding's comments on the topic:

Authentication is orthogonal. Cookies are also orthogonal when they are simply used for content negotiation or authentication. However, Cookie authentication is not allowed in REST because it lacks visibility, which causes security problems because the other components don't know it is sensitive information.

EDIT (further comments on the security aspects):

I realise Roy Fielding's comments in the message I've quoted is against cookies for security reasons. He's right of course. However, in my opinion, it's harder to protect against CSRF via Basic/Digest/Cert (which wasn't really on the radar in 2003, date of that message) than against cookie theft. It depends on the implementation of course. There isn't a perfect solution, but if you use cookies, use secure cookies, over HTTPS.

OTHER TIPS

I see no problem with using a cookie to maintain this information on the client side. Cookies only become a problem when they are used as pointers to some server side session state.

The main thing you have to be concerned about is the security of the information in the cookie. You probably don't want to put the clear text password in the cookie :-)

  • By default browsers don't ask for crendentials again when you refresh a page. You may want to look into this, because if you fix this then your problem is solved.
  • You could maintain a REST service for the most part, except that the user can authenticate either with HTTP or with a cookie. I.e. the service also works if you do not have the cookie.

Regards,

Abby.

If you return a session ID of some sort after authentication and have it passed in with each call, this really isn't much different than passing the authentication credentials with each call. In terms of performance, the latter can still cache the credentials, so there's no performance hit. In terms of security, not having to keep the credentials around is better, since sessions expire but credentials (usually) do not. Arguably, avoiding sessions is more robust, as the server can forget everything between calls but still work.

In short, there's no overwhelmingly strong argument in either direction, and you probably shouldn't get hung up on whether you're being sufficiently "pure" in your commitment to REST. The real issue is the behavior of the client, and that's something you can tweak independently of this, as Sjoerd suggests.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top