Do sessions really violate RESTfulness?
Asked Answered
B

9

563

Is using sessions in a RESTful API really violating RESTfulness? I have seen many opinions going either direction, but I'm not convinced that sessions are RESTless. From my point of view:

  • authentication is not prohibited for RESTfulness (otherwise there'd be little use in RESTful services)
  • authentication is done by sending an authentication token in the request, usually the header
  • this authentication token needs to be obtained somehow and may be revoked, in which case it needs to be renewed
  • the authentication token needs to be validated by the server (otherwise it wouldn't be authentication)

So how do sessions violate this?

  • client-side, sessions are realized using cookies
  • cookies are simply an extra HTTP header
  • a session cookie can be obtained and revoked at any time
  • session cookies can have an infinite life time if need be
  • the session id (authentication token) is validated server-side

As such, to the client, a session cookie is exactly the same as any other HTTP header based authentication mechanism, except that it uses the Cookie header instead of the Authorization or some other proprietary header. If there was no session attached to the cookie value server-side, why would that make a difference? The server side implementation does not need to concern the client as long as the server behaves RESTful. As such, cookies by themselves should not make an API RESTless, and sessions are simply cookies to the client.

Are my assumptions wrong? What makes session cookies RESTless?

Bodice answered 20/5, 2011 at 6:13 Comment(13)
I've covered that exact issue here: https://mcmap.net/q/56277/-rest-complex-applications/…Mandler
To add to that, if you're only using the session for authentication, then why not use the provided headers? If not, and you're using the session for other state of the conversation, then that's violating the Stateless constraint of REST.Mandler
@Will Thanks. It seems you're talking about sessions for temporarily storing user submitted data, while in my case I'm just talking about them as an implementation detail for authentication. Might this be where the disagreement comes from?Bodice
@Will Hartung: no significant difference from the protocol point of view. Filter should also be persisted on the server side and filter id should be always passed. 100% the same as with the sessions.Canned
@Bodice My only point is that if you're going to use a header to represent an authentication token, HTTP provides one beyond a generic cookie. So, why not use that and keep the free semantics you get with it (anyone seeing the payload can see there's an authentication token assigned to it).Mandler
@Canned It's not just about protocol, it's about semantics also.Mandler
@Will So the whole debate is merely a syntax issue? :) If the Authorization header behaved exactly the same as a session cookie it'd be perfectly RESTful? I agree that cookies feel somewhat "dirty", but there's no technical difference.Bodice
@Will Hartung: still no see any difference. You've given the different name to the same technique. We can name it filter, but it still is a session.Canned
Sure, but then why not make up your own headers, or hijack some other header for the auth token. Use the X-XYZZY header. It's just syntax right? The headers convey information. The Authorization header is more "self-documenting" than your cookie is, because "everyone" know what the Auth header is for. If they just see JSESSIONID (or whatever), they can't make any assumptions, or worse, make the wrong assumptions (what else is he storing in the session, what else is this used for, etc.). Do you name your variables in your code Aq12hsg? No, of course not. Same thing applies here.Mandler
@Canned No, it's a Filter. A Filter has different semantics than a Session. Different lifecycle, different workflow, different purpose.Mandler
@Will Hartung: Can't get the idea then :-S From your post I've found them quite similar.Canned
This opinion based question is a violation of the rules. Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.Thrash
@Bodice I noticed you asked this question 12 years but I have a similar question #77444665 I am quite confused to see people use Session-based Authentication and Cookie-based Authentication interchangeably as if Token Authentication can NOT do session control. Can you take a look? I would like to know your opinion.Pinfeather
R
339

First, let's define some terms:

  • RESTful:

    One can characterise applications conforming to the REST constraints described in this section as "RESTful".[15] If a service violates any of the required constraints, it cannot be considered RESTful.

    according to wikipedia.

  • stateless constraint:

    We next add a constraint to the client-server interaction: communication must be stateless in nature, as in the client-stateless-server (CSS) style of Section 3.4.3 (Figure 5-3), such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.

    according to the Fielding dissertation.

So server side sessions violate the stateless constraint of REST, and so RESTfulness either.

As such, to the client, a session cookie is exactly the same as any other HTTP header based authentication mechanism, except that it uses the Cookie header instead of the Authorization or some other proprietary header.

By session cookies you store the client state on the server and so your request has a context. Let's try to add a load balancer and another service instance to your system. In this case you have to share the sessions between the service instances. It is hard to maintain and extend such a system, so it scales badly...

In my opinion there is nothing wrong with cookies. The cookie technology is a client side storing mechanism in where the stored data is attached automatically to cookie headers by every request. I don't know of a REST constraint which has problem with that kind of technology. So there is no problem with the technology itself, the problem is with its usage. Fielding wrote a sub-section about why he thinks HTTP cookies are bad.

From my point of view:

  • authentication is not prohibited for RESTfulness (otherwise there'd be little use in RESTful services)
  • authentication is done by sending an authentication token in the request, usually the header
  • this authentication token needs to be obtained somehow and may be revoked, in which case it needs to be renewed
  • the authentication token needs to be validated by the server (otherwise it wouldn't be authentication)

Your point of view was pretty solid. The only problem was with the concept of creating authentication token on the server. You don't need that part. What you need is storing username and password on the client and send it with every request. You don't need more to do this than HTTP basic auth and an encrypted connection:

Figure 1. - Stateless authentication by trusted clients

  • Figure 1. - Stateless authentication by trusted clients

You probably need an in-memory auth cache on server side to make things faster, since you have to authenticate every request.

Now this works pretty well by trusted clients written by you, but what about 3rd party clients? They cannot have the username and password and all the permissions of the users. So you have to store separately what permissions a 3rd party client can have by a specific user. So the client developers can register they 3rd party clients, and get an unique API key and the users can allow 3rd party clients to access some part of their permissions. Like reading the name and email address, or listing their friends, etc... After allowing a 3rd party client the server will generate an access token. These access token can be used by the 3rd party client to access the permissions granted by the user, like so:

Figure 2. - Stateless authentication by 3rd party clients

  • Figure 2. - Stateless authentication by 3rd party clients

So the 3rd party client can get the access token from a trusted client (or directly from the user). After that it can send a valid request with the API key and access token. This is the most basic 3rd party auth mechanism. You can read more about the implementation details in the documentation of every 3rd party auth system, e.g. OAuth. Of course this can be more complex and more secure, for example you can sign the details of every single request on server side and send the signature along with the request, and so on... The actual solution depends on your application's need.

Rotor answered 1/12, 2013 at 12:15 Comment(22)
Yes, you are completely right. Since I have posted this question I've totally come around to seeing that. Session cookies aren't anything special when looked at in the technical details, but that's missing the forest for the trees. Accepted your answer because of the nice charts. ;)Bodice
I am not sure whether all of them are okay or not. I found a better chart here: i.stack.imgur.com/snQSG.png about oauth. So I think now that authorization must be a layer between the REST client and the REST service, and the REST service should not know about the permissions or anything else. Only that way is it okay I think. This approach reduces the options by developing REST API-s, but I think it is still usable. I try to create an example application to proof that ASAP.Rotor
Ok, I rethought, the response of the REST service should not depend on the authorization, so I think the first 2 solutions are 100% okay, and the others are okay if the service uses the information only to decide whether it allows the request or not. So I think the user permissions should effect on the representation of the current resource.Rotor
I'll create a question about the permissions dependency of representations. I'll extend this answer as soon as I got the proper solution.Rotor
@inf3rno, it is true that a fully RESTful service cannot depend on session cookies for authentication in the way that it is traditionally implemented. However, you can use cookies to perform authentication if the cookie contains all the state information the server will later need. You can also make the cookie secure from tampering by signing it with a public/private key pair. See my comments below.Phagy
@Phagy : Yes, I agree. Traditional sessions would store application state and resource state in the same place on the server, so using them is not restful... Using cookies is a different thing. You store cookies on client side, so it can contain application state.Rotor
@Phagy I'm running a SPA and it seems to me that there isn't any way for me to have a public / private key setup that isn't plaintext somewhere. I've also heard of some schemes where the cookie data stores all the permissions, and by encrypting / hashing the cookie (they referenced AWS and HMAC), you can save yourself a lot of db calls to verify permissions. Do either of those sound feasible?Lydell
@DerekPerkins I'm getting by with tamper-proof cookies as per this article: hacks.mozilla.org/2012/12/… Very interesting stuff. A bit specific though. YMMV.Azotize
Removed the old figures, simplified the explanation.Rotor
This question is difficult to resolve, I think that in practice, tools must be at developper service and not the inverse, for me Restful (as any other "tool" or method of working) is not a wikipedia definition. If you have to make things simple to solve your needs then It doesn't matter if you violate or not Restful, If that worries to you then invent a new term and call it: Stateful, I remember back in nineties when may purists used to say: Absolutely NO! to Dynamic HTML, and now you see...Dementia
@Dementia There is a very good definition about what REST is and what not. The only problem here (I think) that people are lazy to read the Fielding dissertation and they call everything as REST, RESTful, etc..., which uses resources and HTTP methods for CRUD. REST is more than that. You example of dynamic HTML was a completely different issue, since it was an innovation and not the misunderstanding of a well described technology.Rotor
@inf3rno, I understand your point of view, human being need definitions, that make them feel more confortable, is in our nature (the problem with trying to define every thing and being strict its the oposite of being creative). My point was that. Sorry if I was out of subject opening the discussion in this regard. We are not computers, after all ;) ... there are three phrases that guide my thinking, no matter what others would say : "The end justifies the means","everything is relative" and "I do not agree with what you have to say, but I'll defend to the death your right to say it". RegardsDementia
A completely off-topic sub-question. These diagrams, you used to provide images to your answer are lovely. Any chance, you can tell the secret, which software allows drawing so fabulous diagrams?Ignition
This question seems to make the assumption that sessions are being stored on the server, when many frameworks allow users to store sessions in the database, making load balancing work just fine. If this is used, would this not qualify?Thalweg
@Eckster By REST most of the clients are on server side, so the answer depends on what sessions on what server... By huge load you will need horizontal scaling, sometimes on multiple different locations around the world. That means multiple different session storages which you need to sync somehow. By smaller loads you can handle with a single server, storing sessions along with the resource state does not hurt that much. Ofc. this is just one argument against "server side sessions", there are many more...Rotor
You said: "By session cookies you store the client state on the server and so your request has a context. Let's try to add a load balancer and another service instance to your system. In this case you have to share the sessions between the service instances. It is hard to maintain and extend such a system". But isn't it the same for the server to verify the username and password?Suffuse
@SiminJie If you maintain the session on server side and you have multiple servers, then you have to sync between these servers, so for example when any of them goes down, then another can take its place without losing any session data. This session synchronization is the cause of bad horizontal scalability. Maintaining the session on the client eliminates this problem. Making the username and password verification faster is not a hard problem; for example you can use an in-memory cache on the actual server.Rotor
@SiminJie I think you have to ask yourself whether you really need a REST API. It is typically not the reasonable solution. I mean there are many constraints most devs don't understand or care about. It requires a lot of learning to do it properly and the advantages worth the effort only by really big services. It is a lot easier to do what you already understand and try this out with a hobby project.Rotor
"This session synchronization is the cause of bad horizontal scalability.". Isn't the username and password synchronization a cause of bad horizontal scalability? Once you update the password, all servers should know it.Suffuse
@SiminJie Updating the password is a rare event. Updating a session variable is a frequent event...Rotor
What do you think about an API key for frequency control? Is this a session or token?Suffuse
I don't understand why everyone seems to accept the comment you should store passwords on the client side and send them with every request. This is a very bad practice and endangers your customers sensitive data. An unhashed password (which it would have to be to send it over and over) should never be stored anywhere. If we accept this then you are using tokens as most authentication systems do, in which case whatever mechanism we use to scale the tokens repository will have mostly equal scalability concerns as any session scalability.Edmundoedmunds
O
368

First of all, REST is not a religion and should not be approached as such. While there are advantages to RESTful services, you should only follow the tenets of REST as far as they make sense for your application.

That said, authentication and client side state do not violate REST principles. While REST requires that state transitions be stateless, this is referring to the server itself. At the heart, all of REST is about documents. The idea behind statelessness is that the SERVER is stateless, not the clients. Any client issuing an identical request (same headers, cookies, URI, etc) should be taken to the same place in the application. If the website stored the current location of the user and managed navigation by updating this server side navigation variable, then REST would be violated. Another client with identical request information would be taken to a different location depending on the server-side state.

Google's web services are a fantastic example of a RESTful system. They require an authentication header with the user's authentication key to be passed upon every request. This does violate REST principles slightly, because the server is tracking the state of the authentication key. The state of this key must be maintained and it has some sort of expiration date/time after which it no longer grants access. However, as I mentioned at the top of my post, sacrifices must be made to allow an application to actually work. That said, authentication tokens must be stored in a way that allows all possible clients to continue granting access during their valid times. If one server is managing the state of the authentication key to the point that another load balanced server cannot take over fulfilling requests based on that key, you have started to really violate the principles of REST. Google's services ensure that, at any time, you can take an authentication token you were using on your phone against load balance server A and hit load balance server B from your desktop and still have access to the system and be directed to the same resources if the requests were identical.

What it all boils down to is that you need to make sure your authentication tokens are validated against a backing store of some sort (database, cache, whatever) to ensure that you preserve as many of the REST properties as possible.

I hope all of that made sense. You should also check out the Constraints section of the wikipedia article on Representational State Transfer if you haven't already. It is particularly enlightening with regard to what the tenets of REST are actually arguing for and why.

Oddball answered 20/5, 2011 at 6:36 Comment(16)
That's exactly how I see REST as well. As far as I'm aware it's virtually impossible to create an authentication mechanism that is not stateful to some degree, so if at all authentication in general is RESTless.Bodice
I would rephrase your initial statement. Only use REST if the constraints of REST make sense of your application. You are free to apply a subset of those constraints and you will get a subset of the benefits. However, at that point you have created your own architectural style. That's not a bad thing though, in fact that's what the first four chapters of Roy's dissertation are about, principled design. REST was just one example.Undemonstrative
@Jared Are you sure the Google auth token doesn't have the expiry date encoded into it? Doesn't seem like it would be two hard to do.Undemonstrative
@Darrel A fair enough point. I'm honestly not sure how Google does it, but the expiration time could be encoded into the authentication token. I believe my larger point still stands though. There are some types of state that simply must be maintained and as long as you understand why REST calls for statelessness, you can violate it in a way that makes sense with out many repercussions on the rest of the system and the advantages of a RESTful architecture.Oddball
Since no other arguments have been made so far, I'm accepting this well written response. I think the important part is that stateless server does not mean stateless server, something that I think is often misunderstood or misapplied. The server may (and usually must) have any state it wants, as long as it behaves idempotent.Bodice
I've heard so much preaching that sessions are not restful. HTTP basic authentication is a real step backwards if you're trying to build a web app though.Matrilineage
It is possible to create a perfectly RESTful authentication system. If Google encodes the authentication information, i.e. expiration date plus a token encoded by a private key known to all the Google servers, then it could be entirely RESTful. I'm not for religious wars but if people are going to call their APIs RESTful then they should know what that means. There are too many knuckleheads throwing around the latest buzzwords with no idea what they mean.Phagy
@jcoffland, if authentication state cannot be validated by a server, it can be forged. I could reverse engineer my token to alter my expiry, for instance. Or I could pretend to be someone else by taking their authentication token. It comes down to what's more important to the developer or organization: Adherence to an application architectural style or protection of identity.Bubble
@Micah Henning, you are making the false assumption that the server requires state information to validate the authentication token. We can reasonably assume you cannot forge a token that was signed by a public/private key pair if you don't know the private key. To verify the token is valid all you need is the public key. I still hold that completely RESTful authentication is possible.Phagy
@Phagy Yes, I completely agree. Your comment got me thinking... So I created a stateless and sessionless authentication and authorization library based loosely on the design of Kerberos. It works wonderfully, and appears to be very secure. However, because GET requests can't dependably carry body data, every protected resource which should be accessed via GET has to instead be accessed via POST or PUT. I haven't found a way to address that yet.Bubble
@MicahHenning, if you don't have the possibility to send body-data, why not use the HTTP header WWW-Authenticate for that? Take Amazon as an inspiration resource: docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html, they defined AWS aside of Digest and Basic. The browser probably does not know how to handle AWS authentications, so he won't show the login window, if you didn't want the browser to show it and therefore decided not to use this header.Satchel
@Satchel Thanks for that! I'll look into it in more detail soon.Bubble
@Phagy - I think you are saying that using a token that includes an expiry and signature, you can have a truly stateless RESTful authentication solution. But practically, there is no way to invalidate this token. If the token is long-lived, then you have a security problem if the token is stolen. If the token is short-lived, you have to keep regularly generating new tokens (which involves getting the user to enter their username & password - and in the end, isn't the user's password state anyway??) (Not trying to be argumentative, just trying to get my head around this)Townsville
@James, If a long-lived token is stolen that means the user's machine was compromised, in which case, all bets are off. However, short lived tokens are an option.You could allow the user to renew the token with the old one while it is still live. This avoids the problem of having to reauthenticate but is tricky and an adversary could do the same. The user's password is state. Note, that the user could present an old token plus the password, encrypted. Only the server could decrypt the old token and check the password.Phagy
@James, If a long-lived token is stolen that means the user's machine was compromised, in which case, all bets are off. However, short lived tokens are an option. The user could present an old token plus the password, encrypted. Only the server could decrypt the old token and check the password. Then it would issue a new token. Alternatively, the user could present an unexpired token and ask for it to be refreshed. Of course an adversary could do this as well. I agree passwords are state but the state can be kept client side.Phagy
First of all, REST is not a religion and should not be approached as such. While there are advantages to RESTful services, you should only follow the tenets of REST as far as they make sense for your application. - however, I might make YOU a religion for saying that. Thank you. Use what works for your purposes...what a concept.Fluent
R
339

First, let's define some terms:

  • RESTful:

    One can characterise applications conforming to the REST constraints described in this section as "RESTful".[15] If a service violates any of the required constraints, it cannot be considered RESTful.

    according to wikipedia.

  • stateless constraint:

    We next add a constraint to the client-server interaction: communication must be stateless in nature, as in the client-stateless-server (CSS) style of Section 3.4.3 (Figure 5-3), such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.

    according to the Fielding dissertation.

So server side sessions violate the stateless constraint of REST, and so RESTfulness either.

As such, to the client, a session cookie is exactly the same as any other HTTP header based authentication mechanism, except that it uses the Cookie header instead of the Authorization or some other proprietary header.

By session cookies you store the client state on the server and so your request has a context. Let's try to add a load balancer and another service instance to your system. In this case you have to share the sessions between the service instances. It is hard to maintain and extend such a system, so it scales badly...

In my opinion there is nothing wrong with cookies. The cookie technology is a client side storing mechanism in where the stored data is attached automatically to cookie headers by every request. I don't know of a REST constraint which has problem with that kind of technology. So there is no problem with the technology itself, the problem is with its usage. Fielding wrote a sub-section about why he thinks HTTP cookies are bad.

From my point of view:

  • authentication is not prohibited for RESTfulness (otherwise there'd be little use in RESTful services)
  • authentication is done by sending an authentication token in the request, usually the header
  • this authentication token needs to be obtained somehow and may be revoked, in which case it needs to be renewed
  • the authentication token needs to be validated by the server (otherwise it wouldn't be authentication)

Your point of view was pretty solid. The only problem was with the concept of creating authentication token on the server. You don't need that part. What you need is storing username and password on the client and send it with every request. You don't need more to do this than HTTP basic auth and an encrypted connection:

Figure 1. - Stateless authentication by trusted clients

  • Figure 1. - Stateless authentication by trusted clients

You probably need an in-memory auth cache on server side to make things faster, since you have to authenticate every request.

Now this works pretty well by trusted clients written by you, but what about 3rd party clients? They cannot have the username and password and all the permissions of the users. So you have to store separately what permissions a 3rd party client can have by a specific user. So the client developers can register they 3rd party clients, and get an unique API key and the users can allow 3rd party clients to access some part of their permissions. Like reading the name and email address, or listing their friends, etc... After allowing a 3rd party client the server will generate an access token. These access token can be used by the 3rd party client to access the permissions granted by the user, like so:

Figure 2. - Stateless authentication by 3rd party clients

  • Figure 2. - Stateless authentication by 3rd party clients

So the 3rd party client can get the access token from a trusted client (or directly from the user). After that it can send a valid request with the API key and access token. This is the most basic 3rd party auth mechanism. You can read more about the implementation details in the documentation of every 3rd party auth system, e.g. OAuth. Of course this can be more complex and more secure, for example you can sign the details of every single request on server side and send the signature along with the request, and so on... The actual solution depends on your application's need.

Rotor answered 1/12, 2013 at 12:15 Comment(22)
Yes, you are completely right. Since I have posted this question I've totally come around to seeing that. Session cookies aren't anything special when looked at in the technical details, but that's missing the forest for the trees. Accepted your answer because of the nice charts. ;)Bodice
I am not sure whether all of them are okay or not. I found a better chart here: i.stack.imgur.com/snQSG.png about oauth. So I think now that authorization must be a layer between the REST client and the REST service, and the REST service should not know about the permissions or anything else. Only that way is it okay I think. This approach reduces the options by developing REST API-s, but I think it is still usable. I try to create an example application to proof that ASAP.Rotor
Ok, I rethought, the response of the REST service should not depend on the authorization, so I think the first 2 solutions are 100% okay, and the others are okay if the service uses the information only to decide whether it allows the request or not. So I think the user permissions should effect on the representation of the current resource.Rotor
I'll create a question about the permissions dependency of representations. I'll extend this answer as soon as I got the proper solution.Rotor
@inf3rno, it is true that a fully RESTful service cannot depend on session cookies for authentication in the way that it is traditionally implemented. However, you can use cookies to perform authentication if the cookie contains all the state information the server will later need. You can also make the cookie secure from tampering by signing it with a public/private key pair. See my comments below.Phagy
@Phagy : Yes, I agree. Traditional sessions would store application state and resource state in the same place on the server, so using them is not restful... Using cookies is a different thing. You store cookies on client side, so it can contain application state.Rotor
@Phagy I'm running a SPA and it seems to me that there isn't any way for me to have a public / private key setup that isn't plaintext somewhere. I've also heard of some schemes where the cookie data stores all the permissions, and by encrypting / hashing the cookie (they referenced AWS and HMAC), you can save yourself a lot of db calls to verify permissions. Do either of those sound feasible?Lydell
@DerekPerkins I'm getting by with tamper-proof cookies as per this article: hacks.mozilla.org/2012/12/… Very interesting stuff. A bit specific though. YMMV.Azotize
Removed the old figures, simplified the explanation.Rotor
This question is difficult to resolve, I think that in practice, tools must be at developper service and not the inverse, for me Restful (as any other "tool" or method of working) is not a wikipedia definition. If you have to make things simple to solve your needs then It doesn't matter if you violate or not Restful, If that worries to you then invent a new term and call it: Stateful, I remember back in nineties when may purists used to say: Absolutely NO! to Dynamic HTML, and now you see...Dementia
@Dementia There is a very good definition about what REST is and what not. The only problem here (I think) that people are lazy to read the Fielding dissertation and they call everything as REST, RESTful, etc..., which uses resources and HTTP methods for CRUD. REST is more than that. You example of dynamic HTML was a completely different issue, since it was an innovation and not the misunderstanding of a well described technology.Rotor
@inf3rno, I understand your point of view, human being need definitions, that make them feel more confortable, is in our nature (the problem with trying to define every thing and being strict its the oposite of being creative). My point was that. Sorry if I was out of subject opening the discussion in this regard. We are not computers, after all ;) ... there are three phrases that guide my thinking, no matter what others would say : "The end justifies the means","everything is relative" and "I do not agree with what you have to say, but I'll defend to the death your right to say it". RegardsDementia
A completely off-topic sub-question. These diagrams, you used to provide images to your answer are lovely. Any chance, you can tell the secret, which software allows drawing so fabulous diagrams?Ignition
This question seems to make the assumption that sessions are being stored on the server, when many frameworks allow users to store sessions in the database, making load balancing work just fine. If this is used, would this not qualify?Thalweg
@Eckster By REST most of the clients are on server side, so the answer depends on what sessions on what server... By huge load you will need horizontal scaling, sometimes on multiple different locations around the world. That means multiple different session storages which you need to sync somehow. By smaller loads you can handle with a single server, storing sessions along with the resource state does not hurt that much. Ofc. this is just one argument against "server side sessions", there are many more...Rotor
You said: "By session cookies you store the client state on the server and so your request has a context. Let's try to add a load balancer and another service instance to your system. In this case you have to share the sessions between the service instances. It is hard to maintain and extend such a system". But isn't it the same for the server to verify the username and password?Suffuse
@SiminJie If you maintain the session on server side and you have multiple servers, then you have to sync between these servers, so for example when any of them goes down, then another can take its place without losing any session data. This session synchronization is the cause of bad horizontal scalability. Maintaining the session on the client eliminates this problem. Making the username and password verification faster is not a hard problem; for example you can use an in-memory cache on the actual server.Rotor
@SiminJie I think you have to ask yourself whether you really need a REST API. It is typically not the reasonable solution. I mean there are many constraints most devs don't understand or care about. It requires a lot of learning to do it properly and the advantages worth the effort only by really big services. It is a lot easier to do what you already understand and try this out with a hobby project.Rotor
"This session synchronization is the cause of bad horizontal scalability.". Isn't the username and password synchronization a cause of bad horizontal scalability? Once you update the password, all servers should know it.Suffuse
@SiminJie Updating the password is a rare event. Updating a session variable is a frequent event...Rotor
What do you think about an API key for frequency control? Is this a session or token?Suffuse
I don't understand why everyone seems to accept the comment you should store passwords on the client side and send them with every request. This is a very bad practice and endangers your customers sensitive data. An unhashed password (which it would have to be to send it over and over) should never be stored anywhere. If we accept this then you are using tokens as most authentication systems do, in which case whatever mechanism we use to scale the tokens repository will have mostly equal scalability concerns as any session scalability.Edmundoedmunds
B
13

Cookies are not for authentication. Why reinvent a wheel? HTTP has well-designed authentication mechanisms. If we use cookies, we fall into using HTTP as a transport protocol only, thus we need to create our own signaling system, for example, to tell users that they supplied wrong authentication (using HTTP 401 would be incorrect as we probably wouldn't supply Www-Authenticate to a client, as HTTP specs require :) ). It should also be noted that Set-Cookie is only a recommendation for client. Its contents may be or may not be saved (for example, if cookies are disabled), while Authorization header is sent automatically on every request.

Another point is that, to obtain an authorization cookie, you'll probably want to supply your credentials somewhere first? If so, then wouldn't it be RESTless? Simple example:

  • You try GET /a without cookie
  • You get an authorization request somehow
  • You go and authorize somehow like POST /auth
  • You get Set-Cookie
  • You try GET /a with cookie. But does GET /a behave idempotently in this case?

To sum this up, I believe that if we access some resource and we need to authenticate, then we must authenticate on that same resource, not anywhere else.

Barbarity answered 24/1, 2013 at 9:52 Comment(8)
In the meantime I came around more to this point of view as well. I do think that technically it makes little difference, it's all just HTTP headers. It's true though that the authentication behavior itself is not RESTful, if login through a separate address is required. So cookies are only a symptom of a larger problem with the authentication system.Bodice
This doesn't really account for the fact that web browsers only support Authorization: Basic or Digest. If you want to do anything more advanced than basic or digest auth (and you should) in a browser context, then you're going to need something other than the Authorization header.Chausses
@OliverCharlesworth, I don't think it's a problem to carry, say, Bearer token in Authorization header, even in a browser context.Barbarity
Because there's no way to get the browser to use a bearer token for e.g. a page request.Chausses
@OliverCharlesworth, I assume it's a rare case when you request HTML page directly from REST API. In common case you have some sort of JS-based client which could compose any Authorization header you like.Barbarity
Absolutely - if you're doing pure JS then things are basically OK (except, for example, Websockets). But my point is that API-based auth isn't necessarily the only consideration in a browser scenario.Chausses
GET /a without a cookie and with a cookie are clearly two different requests, and it is acceptable for them to behave differently.Myopic
To add on to @TRiG, following this logic, GET /a with authentication header is also the same as GET /a without the authentication header, making it equally unusable for REST. If you're going to treat one http header differently from another, you're going to address that at the very least.Tompion
J
11

Actually, RESTfulness only applies to RESOURCES, as indicated by a Universal Resource Identifier. So to even talk about things like headers, cookies, etc. in regards to REST is not really appropriate. REST can work over any protocol, even though it happens to be routinely done over HTTP.

The main determiner is this: if you send a REST call, which is a URI, then once the call makes it successfully to the server, does that URI return the same content, assuming no transitions have been performed (PUT, POST, DELETE)? This test would exclude errors or authentication requests being returned, because in that case, the request has not yet made it to the server, meaning the servlet or application that will return the document corresponding to the given URI.

Likewise, in the case of a POST or PUT, can you send a given URI/payload, and regardless of how many times you send the message, it will always update the same data, so that subsequent GETs will return a consistent result?

REST is about the application data, not about the low-level information required to get that data transferred about.

In the following blog post, Roy Fielding gave a nice summary of the whole REST idea:

http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841

"A RESTful system progresses from one steady-state to the next, and each such steady-state is both a potential start-state and a potential end-state. I.e., a RESTful system is an unknown number of components obeying a simple set of rules such that they are always either at REST or transitioning from one RESTful state to another RESTful state. Each state can be completely understood by the representation(s) it contains and the set of transitions that it provides, with the transitions limited to a uniform set of actions to be understandable. The system may be a complex state diagram, but each user agent is only able to see one state at a time (the current steady-state) and thus each state is simple and can be analyzed independently. A user, OTOH, is able to create their own transitions at any time (e.g., enter a URL, select a bookmark, open an editor, etc.)."


Going to the issue of authentication, whether it is accomplished through cookies or headers, as long as the information isn't part of the URI and POST payload, it really has nothing to do with REST at all. So, in regards to being stateless, we are talking about the application data only.

For example, as the user enters data into a GUI screen, the client is keeping track of what fields have been entered, which have not, any required fields that are missing etc. This is all CLIENT CONTEXT, and should not be sent or tracked by the server. What does get sent to the server is the complete set of fields that need to be modified in the IDENTIFIED resource (by the URI), such that a transition occurs in that resource from one RESTful state to another.

So, the client keeps track of what the user is doing, and only sends logically complete state transitions to the server.

Jarboe answered 13/12, 2013 at 11:20 Comment(1)
I don't see how this sheds any light on the question posed.Phagy
I
2

As I understand, there are two types of state when we are talking about sessions

  • Client and Server Interaction State
  • Resource State

Stateless constraint here refers to the second type in Rest. Using cookies (or local storage) does not violate Rest since it is related to the first.

Fielding says: 'Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.'

The thing here is that every request to be fulfilled on the server needs the all necessary data from the client. Then this is considered as stateless. And again, we're not talking about cookies here, we're talking about resources.

Impolicy answered 12/12, 2021 at 7:28 Comment(0)
E
1

HTTP transaction, basic access authentication, is not suitable for RBAC, because basic access authentication uses the encrypted username:password every time to identify, while what is needed in RBAC is the Role the user wants to use for a specific call. RBAC does not validate permissions on username, but on roles.

You could tric around to concatenate like this: usernameRole:password, but this is bad practice, and it is also inefficient because when a user has more roles, the authentication engine would need to test all roles in concatenation, and that every call again. This would destroy one of the biggest technical advantages of RBAC, namely a very quick authorization-test.

So that problem cannot be solved using basic access authentication.

To solve this problem, session-maintaining is necessary, and that seems, according to some answers, in contradiction with REST.

That is what I like about the answer that REST should not be treated as a religion. In complex business cases, in healthcare, for example, RBAC is absolutely common and necessary. And it would be a pity if they would not be allowed to use REST because all REST-tools designers would treat REST as a religion.

For me there are not many ways to maintain a session over HTTP. One can use cookies, with a sessionId, or a header with a sessionId.

If someone has another idea I will be glad to hear it.

Eggett answered 16/6, 2015 at 9:49 Comment(0)
B
0

i think token must include all the needed information encoded inside it, which makes authentication by validating the token and decoding the info https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/

Bel answered 17/5, 2020 at 3:28 Comment(0)
E
-2

No, using sessions does not necessarily violate RESTfulness. If you adhere to the REST precepts and constraints, then using sessions - to maintain state - will simply be superfluous. After all, RESTfulness requires that the server not maintain state.

Exhaust answered 15/12, 2020 at 10:21 Comment(1)
In my opinion, the majority of the responses misunderstand what it means for an API to be RESTful. A RESTful API satisfies the REST constraints: Uniform Interface, Stateless, Cacheable, Client-Server, Layered System, Code on Demand. It is quite possible for your API to implement sessions while satisfying these constraints.Exhaust
F
-3
  1. Sessions are not RESTless
  2. Do you mean that REST service for http-use only or I got smth wrong? Cookie-based session must be used only for own(!) http-based services! (It could be a problem to work with cookie, e.g. from Mobile/Console/Desktop/etc.)
  3. if you provide RESTful service for 3d party developers, never use cookie-based session, use tokens instead to avoid the problems with security.
Fortson answered 20/5, 2011 at 6:37 Comment(1)
the cookie should not be used to store a session key for a session on the server which holds the authentication token. but if the cookie holds the authentication token itself it's a feasible solution. (of course the cookie should be httponly and secured)Industrials

© 2022 - 2024 — McMap. All rights reserved.