Cookies and the RESTful API

Right, after my presentation at PHPLondon this month, the most contentious issue was that of using cookies with your REST API. I said, in no uncertain terms, that you shouldn’t do it. There were a few cries from the audience which were akin to the flapping you hear in a parliamentary broadcast, Derick Rethans didn’t agree but had the grace not to publicly embarrass me* and one comment on the original post requesting a clarification of my statement.

So, to clarify!

One of the most important constraints of REST is that it should be stateless, that is, every request made to API should contain everything the application needs in order to service the request. Now, at it’s most terse, that is my clarification, however, the quicker witted and cleverer among you will be proud to announce that a cookie is part of a HTTP request, and you’d be right, so, more clarification is needed.

In order to get to my decision that cookies shouldn’t be used with a REST API, you have to consider HATEOAS (Hypertext As The Engine Of Application State). What this means is that, a client only needs to know one, well published, end point to your entire API and from there, they can navigate the whole damn thing. Many people have blogged on this (including the big man himself), so I shan’t go into it right now, take a look at those links, but it’s safe to say that your clients shouldn’t be building their own URIs, they should be given the URIs from the API. Following this through to it’s logical conclusion means that the client shouldn’t be storing anything that isn’t the well published end point, because you, as the service provider, could change the requirement of whatever it is the client has stored as a cookie on a whim and then the client is banjaxed.

An example you say? OK. Let’s assume for a moment that we all agree that storing login information on the client is NOT GOOD. Right? (Consider XSS briefly and you’ll understand why – although less relevant nowadays, it’s still relevant (just)). OK, so the only other logical thing we might want to store in a cookie is an authentication token. That seems fairly harmless in it’s implementation, no? Yes it is and really, we could end the post here as, at a push, this is probably the one thing that IS OK to store in a cookie.

But I don’t sanction it.

Why? Because it doesn’t adhere to the constraints of HATEOAS and statelessness. Now the client has a cookie with an authentication token in it, you cannot change the way you authenticate, or the way the token is created without breaking the link between your API and each client that is using that token. If you publish a change to your REST API which handles the tokens differently, each and every cookie token will be useless.

Granted, this example doesn’t really offer anything that couldn’t be fixed with another login, but that’s not the point. The point is, it’s not RESTful.

To wit; this is a rule you can break and, probably, get away with it. However, you’ll feel dirty as it won’t be REST; try not to do it, make Roy happy.

*Although, he did heckle me on many other points. 😉

Advertisements

10 thoughts on “Cookies and the RESTful API

  1. Thanks for the write up, now I could understand what this was about. Thank you.

    And I might be wrong but I considered cookies to be part of HTTP but don’t stress me. It will add state and as I understand, you think that’s inappropriate for REST.

  2. I agree with you that REST API must be stateless, but I think that with a little trick you can store the client authenticator token and continue with your stateless API.

    I am considering to store the client ID crypted with RSA public/private algorithm only known by the server API in order to recover the client info in each request without session maintenance. You must treat this crypted client ID as a season cookie, marked as secured and httponly for security reasons.

    I think that these scenario is restful compatible and secure but you will penalize performance with crypt/decrypt in every secured request.

  3. REST does not demand that interaction with the server be stateless. It demands that the server does not manage state. REST is all about stateful transactions with the server, but the client maintains that state, not the server. It is “REpresentational State Transfer” … it implies statefulness in its very name.

    Cookies do not represent the evil of state. State is allowed, so long as its driven by the client, and cookies are, indeed, driven by the client. The evil here is in that the client is not in full control of that state. All state should be represented in the URI where the client is aware of and can manage any stateful values applied to the URI.

    However, one thing that is being overlooked here on the topic of cookies is the usefulness of taking some responsibility away from the client. It is sometimes very useful to apply this logic to a suite of in-house APIs: “While all of our APIs were developed over time (perhaps over a decade or longer) by different people and with a dizzying array of buzzwords in active use at the various times they were developed (SOAP! Corba! JSON-RPC! REST!), one thing will be enforced uniformly across the enterprise: User validation.” That’s hard to do without cookies. On the other hand, if you’re building from the ground-up and have full control over every API your company will expose, you can probably do this via the URI.

  4. Most people come up with their own opinions, etc. having never read the actual document on REST. The author didn’t decide that cookies violate REST, it’s written in the dissertation that cookies violate REST.

    Moving past that, developers are going to do what they want, but if they are explaining their personal opinion, they shouldn’t call it REST. It’s an opinion, which everyone is entitled to, but developers aren’t entitled to their own facts.

    http://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm
    6.3.4.2 Cookies
    “An example of where an inappropriate extension has been made to the protocol to support features that contradict the desired properties of the generic interface is the introduction of site-wide state information in the form of HTTP cookies [73]. Cookie interaction fails to match REST’s model of application state, often resulting in confusion for the typical browser application.”
    “Cookies also violate REST because they allow data to be passed without sufficiently identifying its semantics, thus becoming a concern for both security and privacy. “

  5. No one should have the goal of writing an application that is “pure” according to the rules of REST. The goal should also be to write an application that solves the business problem while being secure. If you sacrifice the quality or security of the application in order to have REST purity, I think priorities need to be re-evaluated. That being said, I strive for REST purity, but it is not the “goal”. I also like HATEOAS, but I lean more and more to allowing cookies for storing an access_token in the client because I find it easier to protect the access_token on the client in a cookie than to protect it in WebStorage for my SPA apps.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s