The ‘Why’, ‘What’ and ‘How’ for Authentication in Web App using JWT
When making a website, you may have come across an array of problems. Among which, authentication while logging in a User, comes as a major headache to developers, primarily to those who are just starting out. Tokens and Sessions were created to ease with this very problem.
A Token is a piece of data that has no meaning or use on its own, but when combined with the correct Tokenization system(a process of replacing sensitive data with unique identification symbols that retain all the essential information about the data without compromising its security) becomes a powerful tool for authentication. Whereas, a Session is a system to manage the duration after which a user is logged out automatically.
Usually, we use HTTP protocols while developing and browsing web applications. For proper implementation of tokenization, we need the server to retain some information or status about the user for the duration of multiple requests, but HTTP is stateless protocol, meaning HTTP does not require the server to store information. If you login for one request, the server will have already forgotten you and you will need to login again to make another request. As you can imagine, this can get pretty annoying when performed repeatedly.
To overcome the stateless nature of HTTP requests, we could use either a session-based or token-based authentication.
So, how is session-based authentication implemented for overcoming the stateless nature of HTTP? Session-Based authentication is implemented in two parts:
- An object is stored on the server that remembers if a user is still logged in, it can be a reference to the user profile or maybe a session_ID.
- Cookies on the client-side store's session_ ID that can be referenced on the server against the session _ID stored on the server.
Now you might be wondering how token based authentication helps to overcome the stateless nature of HTTP?
With token based authentication whenever the user sends a request to a server, each request is accompanied by a signed token which the server verifies for authenticity and only then responds to the request.
Most people will prefer token-based authentication(like JWT) for two major reasons; scalability and flexibility. With session-based authentication, the sessions are stored in the server’s memory so scaling becomes an issue when there is a huge number of users using the system at the same time. But with token-based authentication, there is no issue with scaling because the token is stored on the client side. Also, token generation is decoupled from token verification, allowing you the option to handle the signing of tokens on a separate server or even through a different company such us Auth0 and within the token payload you can easily specify user roles and permissions as well as resources that the user can access.
What is JWT?
JSON Web Token (JWT) as the name suggests is token based authentication which is an open, industry standard (RFC 7519) method for representing claims securely between two parties. "Open" meaning anybody can use it. In JWT, the token is encoded from a data payload using a secret. Since the token is encoded you should avoid keeping sensitive information on the payload. The token, when generated, is passed to the client. Whenever the client sends a request to the server, the token is passed along with a request, then the server validates the token and sends back the response. The following diagram shows how JWT works:
The summarization of the above picture is given below:
- A client signs-in using a valid username/password combination to the server.
- The server validates the authentication. If validation is successful, the server creates a JWT token and the client gets JWT token in the response body, else gives an error response.
- Client stores that token in local storage or session storage. Now if the client wants to make any request, JWT token must be passed in request headers like this.
Authorization: Bearer <jwt_token>
- Server upon receiving the JWT token validates its authenticity and sends the successful response or error response based on its validity.
If you want to know more about JWT and its structure please refer to its official documentation https://jwt.io/introduction/
How to use JWT?
There are many libraries available for JWT. The main function of any of these libraries is to generate JWT and validate JWT. You may use any one of these libraries.
Here, I have picked NPM library called jsonwebtoken. This library is primarily for Node.js.
Firstly, let's start by installing jsonwebtoken.
After installing jsonwebtoken we need to import it to start using it.
The above code generates a JWT token which is encoded but not encrypted, so be careful not to include any sensitive information. The jwt.sign function takes the payload, secret and options, as its arguments. The payload contains information about the user and can be used to find out which user is the owner of the token. Options can have an expire time, until which, a token is deemed as valid. The generated JWT token is a string, which may look something like this:
After generating JWT token, it is returned to the client and it must be passed in Authorization header in order to make any request, access resources or to verify that client. The server must always verify the token before giving any success response or an error response.
Since JWT token is encoded it can be easily decoded and hence, easily altered. This may come as a disadvantage to most people, but when some changes are made to token, the signature of the token also changes. A Signature is the function of encoded payload, secret, and algorithm. Which is already being used for the validation of the JWT, so you need not worry about it.
All of this technical jargon is to show you how JWT is better than using a Session-based authentication, and why JWT has become an essential tool for authentication in the privacy-stricken world of today, where data is becoming more and more valuable.