Hello,
In software development, there are some terms that called “Stateful & Stateless".
These 2 terms are essential to determine the architecture of your application. Note that those term is very broad. And I will choose 1 good case that can perfectly represent stateful and stateless, which is Authentication.
In Stateful Authentication, the server will remember / store the user’s piece of state, or data to determine whether this user is authenticated or not.
That information is called a Session. Session has an ID and contains the user’s info, such as username, or email.
Where do we store the session ?
Well, in a traditional stateful application, we store it in the server’s memory (RAM). In a modern application? let’s talk about it later ;).
Since the session data is stored in memory, the authentication service can check the auth status of a certain user pretty fast.
But of course it has a trade-off, storing data in memory increases the RAM usage. If there are so many users, the server can runs out of memory pretty fast.
How do we store data in the server’s memory ?
Well, the easiest way to do it is to use a global variable.
This is what happen when the client is logged in successfully
So, after checking the user’s credential, the server will generate a session ID, and then save a piece of the user’s credential along with the session ID in memory. Then returns the session ID to the client.
There are several ways to give the session ID to the user, the most convential way is to attach the session ID into the response’s cookies, and that cookie will gonna be saved automatically in the client’s application (browser or other app that do the authentication) without client knows about it.
And this is what happen when the client tries to access a protected resource
If the session ID is attached in the cookie, the session ID is automatically included everytime user calls an API.
When the app’s user increases, there’s a moment where one server is not enough anymore. Well we can do a vertical scaling, in which to increase the server’s hardware capacity, like RAM, etc. But it has a limitation on the max capacity can be increased.
Mostly, we do horizontal scaling instead. In which, we increase the amount of servers available.
But, doing so introduces a problem…
Usually, when there are multiple servers, we use another tool called Load Balancer to Balance the server’s load… duh.
Means that, there’s a 50-50 chance that our request will be routed to Server 1, or Server 2. (We use 50-50 for simplicity’s sake).
Let’s say we were routed to the Server 1 for the login action. It’s done smoothly, client gets the session ID.
Then, when you try to request the protected resource…
Guess what, the load balancer hates you, it routes your request to Server 2.
Server 2 has no idea about your session ID, hence it rejects your request and returns Unauthorized.
There are couple ways to fix this.
The most obvious one is to not storing the session information in the server’s memory.
But then, where should we store it ?
Well, we can store it on the DB. Create a table there to store session information.
But, every time a request came in, we need to poke the DB. But it’s slow, especially if you use a RDBMS like MySQL, or PostgreSQL, or SQLServer.
Then how to make it faster ?
Well, I’d say this step is optional, and not necessary. Most of the time, storing the session in the RDMS is fine if the user can tolerate the additional response time for every authenticated request.
But, if we want to make it faster, then use another DB that utilizes in-memory storage. Such as Redis or Memcached.
That way, we can achieve the same performance as using the server’s memory. Keep in mind that, Redis & Memcached is really fast.
That way, even if there are 100 servers, the application could still recognize the user’s sessionID
By looking at the condition aboves, we can conclude that there are PROS & CONS of using Stateful Architecture.
PROS:
CONS:
Well, as the name suggests. Stateless is the complete opposite of stateful. The “session” is managed in the client’s side. As opposed to stateful, which is managed in the server’s side.
After successful login, the app will take the user’s information and encrypt it using a secret key to generate a token, then returns it to the user.
When user tries to access some protected resources, user need to send that token back to the server. Then the server tries to verify the token’s sign using the same secret key. And also verify the token’s expiry. If the verification succeeded, then the server considers this user as an authenticated user.
So, as long as all the servers are using the same secret key, then it’s all good. They can still verify the token’s validity.
The most popular token generation tool out there is called JSON Web Token (JWT). If you want to implement a stateless authentication, i’d strongly suggest you to use it.
To play around with JWT, you can access jwt.io
This is the JWT's content
Red colored line is the header. It represents which encryption algorithm to use.
Purple colored line is the payload. It can contains any information that the server wants to put. So, the more the information, the longer it gets. The longer it gets, the bigger the JWT’s size will be.
Blue colored line is the** signature key**. It’s generated using the secret key I mentioned above.
Other than those, these are the things that you need to be aware of:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlJhbmdnYSBSaWZxaSBQcmF0YW1hIiwiaWF0IjoxNTE2MjM5MDIyfQ.FzSqgN66Jv5iBuFsN5bBosjHT7oQZtD9jEP58p4CXSY
Rangga Rifqi Pratama
on the payload section?By looking at above’s condition, we know that Stateless authentication can solve some problems that Stateful Authentication has. But it comes with trade-off:
PROS:
CONS:
Woah this is a long article.
As Master Oogway said,
There’s no right or wrong in software architecture. There’s only trade-offs
So, choose your trade-offs wisely ;)
Allright, that’s all I can say. I hope you find something useful here.
Reference: