109

I'm specifically interested in how users perform authorized / authenticated operations on a web API.

Are authentication cookies compatible with the REST philosophy, and why?

Brandon Linton
  • 1,665
  • 3
  • 14
  • 9
  • exact duplicate of [restful-authentication](http://stackoverflow.com/questions/319530/restful-authentication) –  Mar 22 '12 at 18:21
  • possible duplicate of [Software architecture for authentication/access-control of REST web service](http://programmers.stackexchange.com/questions/54784/software-architecture-for-authentication-access-control-of-rest-web-service) – FrustratedWithFormsDesigner Mar 22 '12 at 18:24
  • 1
    @JarrodRoberson My understanding was that answers on another site wouldn't qualify the question as duplicate on here – Tom Squires Mar 25 '12 at 16:42
  • that is why there is a *"belongs on stackoverflow"* option under **close** –  Mar 26 '12 at 13:34
  • 7
    @JarrodRoberson based on each site's FAQs, I would argue the question belongs on this site and not Stack Overflow. I'm interested in design methodology / philosophy and tradeoffs regarding this aspect of RESTful architecture. Stack Overflow is meant for implementation questions, where this site is more about design methodologies and tradeoffs. – Brandon Linton Mar 26 '12 at 14:03
  • 1
    I agree with @BrandonLinton here, the question is too broad for Stackoverflow, it is one regarding architecture and design methodology. The OP wants best practice and patterns, suggestions and gotchas - not a specific answer - hence no language has been specified. Hence, it belongs here. – dooburt Dec 24 '12 at 15:33

3 Answers3

101

An ideal ReSTful service allows clients (which may not be in-browser) to perform any needed task in one request; because the full state needed to do that is held by the client, not the server. Since the client has full control of the state, it can create the state on its own (if that is legitimate), and only talk to the API to "get 'er done".

Requiring cookies can make that difficult. For clients besides browsers, managing cookies is a pretty big inconvenience compared to query params, plain request headers or the request body. On the other hand, In browser, using cookies can make lots of things much simpler.

So an API might first look in the Authorization header for the authentication data it needs, since that's probably the place where non-browser clients will prefer to put it, but to simplify and streamline browser-based clients, it might also check for a session cookie for server side log in, but only if the regular Authorization header was missing.

Another example might be a complex request that normally requires lots of parameters set. A non interactive client would have no trouble jamming all of that data into one request, but a HTML form based interface might prefer to break the request into several pages (something like a set of 'wizard' pages) so that users aren't presented with options that are not applicable based on previous selections. All of the intermediate pages could store the values in client side cookies, so that only the very last page, where the user actually submits the request, has any server side effect at all. The API could look for the needed attributes in the request body, and fall back to looking at cookies if the needed parameters weren't there.

Edit: in RE to @Konrad's comment below:

Tokens in comparison are harder to implement especially because you can't easily invalidate the token without storing them somewhere.

er... you are validating the cookies on the server side, right? Just because you told the browser to discard a cookie after 24 hours doesn't mean it will. That cookie could be saved by a highly technical user and reused long after it has "expired".

If you don't want to store session data on the server side, you should store it in the token (cookie or otherwise). A self contained auth token is sometimes called a Macaroon. How this is passed between client and server (whether by cookie, as extra headers, or in the request entity itself) is totally independent of the authentication mechanism itself.

  • 7
    +1, I definitely like the practicality of using the Authorization header but "falling back" to cookies depending on what works best for the client. – Brandon Linton Mar 26 '12 at 14:17
  • I disagree with "For clients besides browsers, managing cookies is a pretty big inconvenience...". Mostly HTTP client libraries support cookies, for example, with `HttpClient` in .NET you can use cookies without any problem and you don't really need to think about it. Tokens in comparison are harder to implement especially because you can't easily invalidate the token without storing them somewhere. – Konrad Aug 31 '18 at 12:26
  • 2
    @Konrad just because it is easy in *some* non-browser clients doesn't mean it's easy in all of them. It's fine if you only need to support the particular client you happen to use, but i interpreted the question to be about public facing API's. in `curl` or `wget`, managing cookies is pretty darn inconvenient and you really do have to think about them a bunch. I replied to your other point by editing my answer. – SingleNegationElimination Sep 01 '18 at 15:10
  • 1
    Beware that simply accepting cookies opens up CSRF vulnerabilities. See also https://security.stackexchange.com/a/166798 – Michael Osl Oct 18 '18 at 12:37
  • _For clients besides browsers, managing cookies is a pretty big inconvenience compared to query params, plain request headers or the request body._ Do you have a good resource explaining that further? Taking Python's `requests` library as an example, passing [cookies](https://requests.readthedocs.io/en/master/user/quickstart/#cookies) works pretty much the same as [query parameters](https://requests.readthedocs.io/en/master/user/quickstart/#passing-parameters-in-urls) or [headers](https://requests.readthedocs.io/en/master/user/quickstart/#custom-headers), at least on a syntax level. – bluenote10 Feb 20 '21 at 14:32
  • I agree with your answer and JWT is now kinda de-facto standard for REST APIs, but in order to pass them as Authorization header, we'd have to store them into local storage which is accessible by js and thus vulnerable to XSS. its recommended to store them in httpOnly cookie. Would you trade-off security at the cost of design spec? and the answer is also pretty old and I am not sure about that time but now cookies are sent and received as just another type of header. and since we're not using session-cookies and whole state is maintained by user why cookies are discouraged in REST APIs – Aniket Kariya Mar 19 '22 at 11:56
  • ++ for general standalone APIs available to the public it might make sense not to use cookies but for APIs that are part of a project it might be required to use cookies and it should be fine to use it no? – Aniket Kariya Mar 19 '22 at 11:59
18

Yes and No - Depends how you use it.

Cookies if used to maintain client state at the client, for the client, of the client and by the client then they are restful.

If you are storing server state into the cookie then you are basically just shifting the load to the client - which isn't restful.

So what are some examples?

Restful:

  • Authentication details or 'is logged in' kinda stuff
  • last viewed page or place in application etc.

Not Restful:

  • Storing session information

Restfulness comes from statelessness - of the server. Clients can maintain application state and send it to the server to say where they are so that the server can decide where to go from there. Basically sessions/states need historical data and are dependent on past requests so to speak, restful applications ideally aren't (It's not viable to have a 100% pure restful application if you are going to have a login screen :)

PhD
  • 2,531
  • 2
  • 18
  • 32
  • 18
    If you store an "isLoggedIn" flag on the client, you might as well use no authentication at all. – tdammers Mar 23 '12 at 06:54
  • This definitely makes sense - storing application state client-side wouldn't be consistent with REST, but client information that it uses to represent itself seems fine. – Brandon Linton Mar 26 '12 at 14:15
  • 1
    I'd like to add that putting authentication information in cookies leaves open the possibility of cross-site request forgery attacks. There are better ways, I suggest copying Amazon: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html – Dobes Vandermeer Jun 16 '14 at 18:11
  • 1
    @tdammers what about if the "isLoggedIn" flag is in a JWT? Then that should be secure, providing the JWT is issued and verified properly. – Aaron J Spetner Aug 26 '17 at 18:34
  • 1
    @AaronJSpetner: [Do not use JWT for sessions](http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/). – tdammers Sep 01 '17 at 17:59
  • @tdammers why not? – Aaron J Spetner Sep 03 '17 at 19:34
  • @AaronJSpetner: click the link, explains it better than I could. – tdammers Sep 04 '17 at 10:11
  • How does this work, with 2FA, isn't there some inherent server-side session information in that case? Am I misunderstanding? – batbrat Sep 27 '19 at 13:04
  • But what is the exact difference between *Authentication details* and *session information*? – BairDev Feb 02 '21 at 16:40
  • From my understanding this one is too broad: *Restfulness comes from statelessness - of the server.* The server ist restful if it does not store or handle the state of the client. – BairDev Feb 02 '21 at 16:43
16

One can use cookies. REST allows them.

REST requires that any session information be stored on the client side, but when it comes to authentication, some information has to stay on the server side for security reasons.

From one of my blog posts, there is a general agreement that authentication data is considered out of scope regarding REST. Hence, it is ok for servers to keep some of this session data on their side.

  • REST is statelessness. https://restfulapi.net/statelessness/ It says "For becoming stateless, do not store even authentication/authorization details of client. Provide credentials with the request. Each request MUST stand alone and should not be affected by the previous conversation happened from the same client in past." – Aleksandr Ryabov Feb 04 '21 at 06:26
  • No, REST does not allow cookies, because a) they are independent of application state; b) they have no defined semantics, cf. [§ 6.3.4.2 Cookies](https://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_3_4_2) of Roy Fielding’s thesis. – Géry Ogam May 22 '21 at 23:00
  • @AleksandrRyabov If a cookie is containing an encrypted claims token with the user ID, it *is* doing the job of passing the credentials with the request. It's taking the place of the Authorization header. – Jez Mar 24 '23 at 19:56