How to understand "RESTful API is stateless"? - rest

I heard that a "RESTful API should be stateless. All state info should be kept on client side".
But when I issue an AJAX call from a web page, I noticed that a session ID cookie is always sent along to the server. With that session ID, I can obtain the session object on the server, and thus I can "get/set some state info in the session".
Does this break the "code of being stateless" for a RESTful API?
ADD 1
(The background of my question is as below.)
I tried to implement a login page by calling a RESTful API to validate a username and a password.
Each time a user attempts to visit a page of my site, a login servlet filter will check the session (this is where getSession() gets called) for that user to see if valid login info exists. If not, the login filter will redirect the user to the login page.
On the login page, an AJAX call is made to a RESTful API on the server with the username and the password. Depending on the result of that RESTful API call, the JavaScript on the page will decide whether to let the user into my site.
So, in this scenario, I kind of have to use session.
The detailed code is located here:
Is this login logic via RESTful call sound?

Simply put: In REST applications, each request must contain all of the information necessary to be understood by the server, rather than be dependent on the server remembering prior requests.
Storing session state on the server violates the stateless constraint of the REST architecture. So the session state must be handled entirely by the client.
Keep reading for more details.
The session state
Traditional web applications use remote sessions. In this approach, the application state is kept entirely on the server. See the following quote from Roy T. Fielding's dissertation:
3.4.6 Remote Session (RS)
The remote session style is a variant of client-server that attempts to minimize the complexity, or maximize the reuse, of the client components rather than the server component. Each client initiates a session on the server and then invokes a series of services on the server, finally exiting the session. Application state is kept entirely on the server. [...]
While this approach introduces some advantages, it reduces the scalability of the server:
The advantages of the remote session style are that it is easier to centrally maintain the interface at the server, reducing concerns about inconsistencies in deployed clients when functionality is extended, and improves efficiency if the interactions make use of extended session context on the server. The disadvantages are that it reduces scalability of the server, due to the stored application state, and reduces visibility of interactions, since a monitor would have to know the complete state of the server.
The stateless constraint
The REST architectural style is defined on the top of a set constraints that include statelessness of the server. According Fielding, the REST stateless constraint is defined as the following:
5.1.3 Stateless
[...] 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. [...]
This constraint induces the properties of visibility, reliability, and scalability:
Visibility is improved because a monitoring system does not have to look beyond a single request datum in order to determine the full nature of the request. Reliability is improved because it eases the task of recovering from partial failures. Scalability is improved because not having to store state between requests allows the server component to quickly free resources, and further simplifies implementation because the server doesn't have to manage resource usage across requests.
Authentication and authorization
If the client requests protected resources that require authentication, every request must contain all necessary data to be properly authenticated/authorized. See this quote from the RFC 7235:
HTTP authentication is presumed to be stateless: all of the information necessary to authenticate a request MUST be provided in the request, rather than be dependent on the server remembering prior requests.
And authentication data should belong to the standard HTTP Authorization header. From the RFC 7235:
4.2. Authorization
The Authorization header field allows a user agent to authenticate itself with an origin server -- usually, but not necessarily, after receiving a 401 (Unauthorized) response. Its value consists of credentials containing the authentication information of the user agent for the realm of the resource being requested. [...]
The name of this HTTP header is unfortunate because it carries authentication instead of authorization data.
For authentication, you could use the Basic HTTP Authentication scheme, which transmits credentials as username and password pairs, encoded using Base64:
Authorization: Basic <credentials>
If you don't want to send the username and password in each request, the username and password could be exchanged for a token (such as JWT) that is sent in each request. JWT can contain the username, an expiration date and any other metadata that may be relevant for your application:
Authorization: Bearer <token>
What might be wrong with your server
Once you have a session indentifier, I guess a HTTP session is being created somewhere in your application. It can be in your own code or in the code of the framework you are using.
In Java applications, you must ensure that the following methods are not getting invoked:
HttpServletRequest#getSession()
HttpServletRequest#getSession(boolean) with true

Related

Does Using Opaque Access Tokens Make My Server Stateful?

I am trying to understand statelessness in restful APIs in the context of authentication. Here's the scenario:
The user logs in.
The server verifies the username and the password, and generates an opaque access token. It caches some information related to this token - for example, the expiration time, the userId, whether this token was explicitly invalidated before it expired, etc.
The token is sent to the client, and the client sends it with every future request.
List item
Fielding's dissertation defines statelessness as:
"...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."
In my example, the client is sending the token with every request, so the first condition is satisfied. However, my server has a context associated with this session that is stored in the sessions cache.
Does this make my application stateful?
If yes, then is it that true statelessness be achieved only if we are using JWTs? I am pondering upon this as JWTs are quite new, so how were architects building truly stateless services before they were invented?
That's right. If you you maintaining the session you are keeping the state in server which makes the application hard to scale. True stateless applications can be scaled out and any server should be able to handle the request.
JWT is popular way to avoid sessions and everything is encapsulated inside the token for any server to auth/Authorize the request and help us achieve stateless application, they come with their own challenges however OpenID connect is the new way for Auth/Authorization.
Before jwt to make application stateless we used to keep session in DB (or Shared Cache) , and any server would like to check the session would have to contact DB.
Hope that Helps!
Briefly: No, such usage of token does not make your application stateful.
Detailed: When we talk about stateless/stateful, we consider usually only the data that affect business logic. Business logic does not usually depend on authentication data. For example, a user sends a request that contains all data needed to place some order. Normally creating an order does not depend on when this user has logged in, on his user ID, etc.

Security Issues with RESTful Authentication & Session Management

I'm trying to implement authentication and session management for a microservice. In order to do the process RESTfully, I understand that I'll need to use some kind of token-based authentication to avoid tracking client session data on the server. The following quote from this answer on the Information Security Stack Exchange nicely sums up my understanding of the implementation:
In Token-based Authentication no session is persisted server-side (stateless). The initial steps are the same. Credentials are exchanged against a token which is then attached to every subsequent request (It can also be stored in a cookie). However for the purpose of decreasing memory usage, easy scale-ability and total flexibility a string with all the necessary information is issued (the token) which is checked after each request made by the client to the server.
From this, I understand how stateless session maintenance is advantageous for scalability, and flexibility as explained. But it seems to me that this leaves the application exposed to some serious problems:
If a hacker somehow intercepts the credential exchange HTTP REST call, they could execute replay attacks on the server get all the information they want.
In fact, since the session token is stored on the client side, couldn't a hacker just retrieve the requisite information from LocalStorage/SessionStorage by debugging the app? Or by monitoring the incoming and outgoing HTTP calls using dev tools? If they get the required token information (even encrypted token information), they could simply start faking REST calls to the server from another window and get all the data they want!
Finally, even if you do give the client a session token, wouldn't the server still have to authenticate that token? In effect, the server would have to maintain session tokens to user mappings...but doesn't that defeat the purpose of a stateless REST-based architecture?
Maybe I am seeing these problems because there is a gap in my understanding. If that's the case, I'd like some clarity of the basic concepts. If not, I'd like to know if there are any techniques to address these specific problems.

Can I use a session identifier in a REST API? [duplicate]

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?
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.
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
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
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.
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.
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.
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.
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.
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/
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.
Sessions are not RESTless
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.)
if you provide RESTful service for 3d party developers, never use cookie-based session, use tokens instead to avoid the problems with security.

Does using tokens break REST principles

Does using tokens for authentication break REST principles, which is supposed to be stateless.
I have an application which is required to be REST and I stored some tokens in a database. Each time a user wants to do an action, they should get a token (by sending a username and a password) and send it to the server with every request.
No they, don't.
A key aspect of something like the authentication header is the fact that it's orthogonal to the request itself. It's a property of the request in the same way that a Content-Type header is.
How Authentication is implemented on the back end is not germane to the discussion as long as results of the requests that submit the header are consistent. There's no reason the process of validating an authentication header can't be a stateless process in and of itself.
The presence and content of the Authentication can certainly impact what a client receives from a request, from a 403 Unauthorized response, to a limited amount of content based on whether the client is, perhaps, using an "admin" token vs. a non-privileged user.
It's also in contrast to a Cookie, which represent Session state (which is not RESTful). This is because the two headers serve different purposes and offer up different application semantics.
Authentication Tokens are a standard way of authenticating REST Clients.
Authentication token themselves do not beak REST principles as long as your API doesn't behave differently based on the Auth token passed to the API.
i.e. if 2 consumers place the same request with different auth token, and they are both allowed to perform that operation, the result should be the same.
You can find more info on REST API authentication here: https://dzone.com/articles/api-security-ways-to-authenticate-and-authorize
No it does not break the rule of being stateless.
Why?
Because the server is not maintaining any session w.r.t the client. It is just validating the token provided by client and returning results based on that.
If its client that has to maintain any data related to the session (which happens in case of tokens since they are sent with every request) then it is not breaking the REST principle, it is still stateless since the server is not maintaining the session or data related to the session.
Hope that helped.
It does break Rest principles because once the service generates a temporary token based on login credentials, the service is no longer stateless. The service has to check with itself if the token has expired yet (the token is part of the system state now), for each call made using that token.
One can't say the session at any point is independent of all the client's previous actions, because if they did not log in correctly, they could not even use the system.
But you should use logins and tokens, and break the Restfulness in this small way for security.

Storing authentication tokens in a RESTful API without using HTTP sessions

I am building a RESTful API with multiple servers and I want to know if it's okay to store the access token in a central database server and then, for every request, verify if this access token is valid by querying the database and then performing the action given.
If I use sessions for this job, will it become non RESTful? Like even if I store the session data in a database? It's been a confusing idea to me for so long.
REST is stateless
REST stands for Representational State Transfer and this architecture was defined by Roy Thomas Fielding in the chapter 5 of his dissertation.
Fielding defined a set of constraints for the REST architecture. One of these constraints is the stateless communication between client and server, defined as following (the highlights are not present in his dissertation):
5.1.3 Stateless
[...] 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. [...]
So, if you keep the session state on the server, you break the stateless constraint. Hence, it's not REST. In REST you won't have a session on the server and, consequently, you won't have session identifiers.
Each request must contain all data to be processed
Each request from client to server must contain all of the necessary information to be understood by the server. With it, you are not depending on any session context stored on the server.
When accessing protected resources that require authentication, for example, each request must contain all necessary data to be properly authenticated/authorized. It means the authentication will be performed for each request.
Have a look at this quote from the RFC 7235 regarding considerations for new authentication schemes:
5.1.2. Considerations for New Authentication Schemes
There are certain aspects of the HTTP Authentication Framework that
put constraints on how new authentication schemes can work:
HTTP authentication is presumed to be stateless: all of the
information necessary to authenticate a request MUST be provided
in the request, rather than be dependent on the server remembering
prior requests. [...]
And authentication data (credentials) should belong to the standard HTTP Authorization header. From the RFC 7235:
4.2. Authorization
The Authorization header field allows a user agent to authenticate
itself with an origin server -- usually, but not necessarily, after
receiving a 401 (Unauthorized) response. Its value consists of
credentials containing the authentication information of the user
agent for the realm of the resource being requested.
Authorization = credentials
[...]
Please note that the name of this HTTP header is unfortunate because it carries authentication data instead of authorization. Anyways, this is the standard header for sending credentials.
Token based authentication
When performing a token based authentication, the tokens are your credentials. In this approach, your hard credentials (username and password) are exchanged for a token that is sent in each request. Again, the authentication must be performed for every request, so you won't take advantage of any stored context on the server.
It's perfectly valid storing your tokens somewhere in your server. And it won't break the stateless constraint of the REST architecture.
Tokens
Basically, the tokens can be opaque (which reveals no details other than the value itself, like a random string) or can be self-contained (like JSON Web Token):
Random String: A token can be issued by generating a random string and persisting it to a database with an expiration date and with a user identifier associated to it.
JSON Web Token (JWT): Defined by the RFC 7519, it's a standard method for representing claims securely between two parties. JWT is a self-contained token and enables you to store a user identifier, an expiration date and whatever you want (but don't store passwords) in a payload, which is a JSON encoded as Base64. The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server. You won't need to persist JWT tokens if you don't need to track them. Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To find some great resources to work with JWT, have a look at http://jwt.io.
There are many databases where you can persist your tokens. Depending on your requirements, you can explore different solutions such as relational databases, key-value stores or document stores.
Your RESTful API would need to be stateless. Stateless means, that it should not rely on prior communication, like in the case of authentication and cookies set before the request in question.
That does not mean however that you can not cache some authentication token on the server side, provided, that a client could make a request without it. This all means, that if the client can fall back to standard HTTP authentication on every request, it should still be ok. The goal with this is to enable load balancing, distribution, and no (or limited) memory use on the server side for conversations.
Other than that, you don't really need to follow all the "rules" if you are not planning to use the benefits it provides. You can, if you want, implement it any way you want as long as the tradoffs are known.
Edit: found a previous discussion on the topic: Do sessions really violate RESTfulness?