In this blog, we are going to discuss how to design a Basic authentication service.
Now, there are the main things we are going to consider while designing a auth. system :
Registration
Login
Sign Out
We are not going to talk about “registration” as it is very simple to implement.
When we make requests on the internet it happens through the http
protocol. But, http
is stateless ( i.e it doesn’t retain any information about the previous requests/interactions made btw the client and the server. )
So, we cannot depend on the protocol for authenticating the user. So we introduce a database to the system. what happens here is when the user login, API generates a session id
and stores it in the database. The database has a session id
table where it stores the session IDs of all the users.
Now, whenever the user logins and makes a request to the API, it is going to check the database for the authenticated user.
Let's take an example.
in this example, Eren makes a request to delete another user (Bob). this request goes to API and then to the database where it compares the session id
with the user’s session IDs in the table to confirm that the request is surely made by Eren and then it carries out the action (i.e. to delete the user).
But, we also have to store this session id
on the client side as we send it with the request to the server to verify the user. So, there are two ways we store these session IDs:
cookies
: The main advantage here is that it is easy to implement this. The server also has access to the cookie storage. The cookie will have information likedomain
,duration
, anddata
. But there’s a catch, it makes the site vulnerable to XSS (Cross-site Scripting) and CSRF (Cross-Site Request Forgery) attacks. It is generally used in very simple services.local storage
: It’s a type of web storage that allows you to store data in it without an expiration date and is comparatively more secure than cookie-based storage of session ids. It is more work to implement it as you have to include the IDs inAUTH
headers of a request.
But, there are also some architectural concerns with this system. Every time a user logins or makes a request it has to make a DB hit. which makes the system vulnerable to DOS(Denial-of-Service) attacks.
Here we introduce JWTs(JSON Web Tokens) to the picture. But, what are JWTs?
JWT: JWT which stands for JSON Web Token is a compact and URL-safe way of transferring data btw the client and the server.
As we can see in the above image JWTs consist of three properties header, payload, and signature. The header
contains the algorithm and the type of data we are using here for transferring, that is JSON in this case always. The second property is payload
which consists of all the app or website data of the user. The third property is the signature,
which is used to verify the integrity of the data. Asymmetric encryption is used here to encrypt the data.
Now, when the user makes a request to the /login
endpoint the API sends back a JSON web token which is stored on the client's device. Now, when the user makes the request to /user
endpoint the token is included in the request, and on the User API the signature of the token is used to verify the integrity of the data.
We can see that the login
and user
APIs are independent of each other which makes them very less vulnerable to attacks.
But But But, there are also some caveats here like if the user wants to keep the token around, it will continue to exist( a solution to this can be, including duration property in payload). And user API will have to accept the incoming requests from the user. That was the benefit we had of having a database as a single source of truth.
Ya, that's all. Overall a few things to consider.
We need state to have authentication.
May need to decentralize auth in Large scale system.