I’m reading Roy Fielding’s dissertation Architectural Styles and the Design of Network-based Software Architectures, which introduces the REST architectural style.
Roy explains that cookies are a violation of REST as they introduce stateful behaviour – cached responses may no longer apply (for example, hitting the back button), and server-side statelessness is a constraint of REST.
There is no reason why the client should not maintain state however, this is perfectly acceptable.
So if I have a RESTful API – for an online store for example – and I want to persist user state client side for a long time – between multiple sessions, are there any alternatives to using cookies to persist local state in modern browsers?
If it matters, I assume I’m running a javascript app in the browser.
Are there any ways I can create client-side-only cookies?
This question is related a similar question about cookies for authentication in REST…
UPDATE:
…but in my case I am not concerned with authentication strategies – just in how to persist state between sessions without sending state to the server.
To give the discussion better context, when talking about cookie based authentication, Roy says:
cookie-based applications on the Web will never be reliable. The same functionality should have been accomplished via anonymous authentication and true client-side state.
7
There’s HTML5 local storage, which allows you to keep data without it contaminating the HTTP requests you make. It’s intended for pretty much exactly this use case: complex Javascript applications that want to store persistent information locally.
http://www.w3.org/TR/webstorage/
Note that REST doesn’t mean banning all state from the server, sometimes you genuinely want to update things; especially in the “airline ticket” example you might want to explicitly create a “reservation” object before payment with a POST that returns a URL for the reservation. The client then hangs onto the URL, but the server-side object exists to prevent booking the same seat twice.
1
The point that Roy Fielding makes about cookies relates to sending these cookies to the server and maintaining state on the server based on those cookies.
Using a cookie purely client-side to store state for any period of time does not violate REST and actually doesn’t concern the server-side at all.
EDIT:
You could store a cookie on a path that is not used by your server. That way you can access it from your javascript, but it will never get sent.
1
You don’t have to use cookies, but if you have secured resources (eg my shopping basket as opposed to your basket) then you do need some way to detect which request corresponds to which of us. That id is usually held in a cookie as the detection is performed on the server via expensive auth mechanisms you want to store temporarily and repeat every request.
logically there’s nothing stopping you from performing the authentication on every request. (except in the real world you won’t do this unless you have, say, client certificates proving your identity to the server)
I imagine you could use some unique identifier that is known to the client, and use that as a mapping between client and secured user id after login instead, but they’re hard to come by and maintain security.
1
You can use cookies to maintain client state, because they are a client side storage mechanism. You can use other client side storage mechanisms, for example websql or localstorage.
The only problem with the cookies, that session cookies are violating the statelessness constraint. So unless you use session cookies you are okay. You should ask yourself what would happen when the server reboots. In the case of session cookies, your session will be lost. In the case of normal cookies, nothing relevant happens, your requests will be responded the same way as before.
I think when the server writes the cookies that is a grey zone thing, especially if we are talking about HTTP-only cookies (which are not accessible in browser javascript). In this case the service directly changes the client state. We could argue that set cookie headers are part of the representation, but that’s a half truth I think. If your REST API has a different domain than your client, then set cookies only on the client domain and access their content for example with client side javascript if we are talking about browsers.
I don’t know whether caching and cookies conflict with each other. I don’t remember such an issue.
You should use the Authorization header instead of cookie, but I think it is not a tragedy if you set the username and password in a HTTP-only header. Or you set a persistent cookie with some hash (if it is registered on the server as a resource for a long while). I think it is still safer than storing this data for example in the localstorage.