a group of cubes that are connected to each other
Fri Feb 03

What Is JWT Authentication?

As a developer, you may have heard of JWT. Maybe you have used it in the past. For you, who are not tech savvy but interested in cyber security features, the knowledge I’d share with you right now may still be useful as understanding the workflow of JWT can often be confusing, especially for the first timer. So, we’re going to cover all things about JWT and how JWT (JSON Web Token) works.

What is JWT?

To get a better understanding of JWT, it is better to first talk about RESTful API where it is mostly used. To simplify, A RESTful API is a type of web service that uses HTTP methods to perform CRUD operations on resources identified by URIs, following a set of architectural constraints and client- server principle, it provides a standard communication between systems. While providing the services, oftentimes the server needs to protect its content where the secure authentication like JWT is needed.

JWT is a standard method to establish two-way communication between client and server securely. By using JWT, the server will be able to verify the client and allow it to be able to communicate with the server within a certain period determined by the server.

In short, JWT is a form of authentication that allows clients and servers to securely communicate within a certain time.

JWT Structure

JWT consists of three main sections where each one is separated by dot. Let’s see the token example below.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header
Example:
{
“alg”: “HS256”,
“typ”: “JWT”
}

This part contains the algorithm used and the token type.

Payload
Example:
{
“sub”: “1234567890”,
“name”: “John Doe”,
“iat”: 1516239022
}

This section contains some information regarding the subject, name, and the time when the token was issued. “sub” specifies the main entity it pertains to which must be unique. The “name” defines the user name and preferably the short one as the goal representation of JWT is to be compact. Therefore, it is better to keep only the necessary information to make it compact and avoid inserting any sensitive data in this section for security reasons. “iat” indicates the time when the JWT was issued.

Signature
Example:
HMACSHA256(
base64UrlEncode(header) + ”.” +
base64UrlEncode(payload),
your-256-bit-secret
)

This is where you include your 256 bit secret. By using a hashing algorithm, all the data above including your 256 bit secret key are encoded. Hashing is the method where the data is encoded in one way. By doing this, if you build a microservices, this secret key will be used to verify and validate the user by implementing the JWT verify method.

Why JWTs?

In any field where the information is sensitive, the risk of stolen credentials can be extremely high. From the security standpoint, the traditional authentication as username and password are unfortunately insufficient to protect the users. This is where JWT has a very crucial role.

Traditional Cookie-Session Based
Authentication.png

In traditional authentication, the authentication relies heavily on cookies and sessions created by the server. Besides, it also relies heavily on humans as users. The overview of how it works is as follows.

In this authentication type, both username and password are required. the client will send its identity set in the cookie header to the server. These credentials will then be verified and stored by the server. The server will create a new session and send the session ID to the client in the form of a cookie header. After that, the client will save it in an active session. After the user logs out, the session will be destroyed both from the client side.

If you look at it, there really isn’t anything wrong with how traditional authentication works. However, there are many drawbacks that you have to consider.

Social Engineering

This approach is more user-driven, which can be very risky from a security perspective. In general, humans are terrible at remembering long and complex passwords which in contrast is very good from a security point of view. Humans are also more vulnerable to any kind of hacking methods like social engineering which can lead to data theft.

CSRF (Cross-Site Request Forgery)

To prevent attacks such as CSRF, the created session must be destroyed. While the traditional authentication has already done it, this is sometimes not enough to ensure that the authentication we do will be truly secure. The attacker may still take advantage of the ‘New Tab’ feature in the browser, where the session is still ongoing. An attacker may trick the victim into authenticating while the attacker’s script is running on another tab that interacts with it.

XSS (Cross-Site Scripting)

[XSS (Cross-Site Scripting)](https://www.binaryte.com/blog/xss-cross-site- scripting-explanation-with-example) is done by utilizing user input made on the website. In this context, the attacker might use the username input to execute the attacker’s malicious script. Even though it is not directly related to how traditional auth works, the risk of data theft with methods such as MITM (Man-In-The-Middle) attacks will be higher as users are required to log in every time they want to use the application.

User Experience

It will be very inconvenient and cumbersome for the user to enter credentials every time the user will use the application or website. We would much prefer a method for the user where they are not required to do this repeatedly yet to still be secure at the same time.

Token-Based Authentication

When talking about token-based authentication, it generally refers to JWT. The way tokens work is slightly different from traditional authentication.

In simple manner, the token-based authentication, users will still require login credentials from the user. The credentials are then sent to the server and the server will verify them. Following verification, the server will return tokens to the user in the form of access tokens and refresh tokens that are only valid for a limited period of time.

The tokens will then be used as authorizations to consume information in JSON format. When the user logs out, the token on the client side will be destroyed or the token is blacklisted on the server side thus invalidating the tokens so the communication can no longer be established.

By comparing both authentication methods, token based-authentication is way more convenient for the user as the users don’t have to login every single time they want to use the service. The authentication is done automatically by the system thus minimizing the risk of any disadvantages mentioned earlier.

How does the JWT work?

Even though it has been briefly explained above, a thorough understanding of how the JWT Token works will be very helpful. It is especially important if we intend to develop applications or websites that implement the JWT standard.

Assume we use two servers where one server will be used to provide the service (Resource Server) while the other one is only for authentication related to JWT (Auth Server). The first server will provide the information in JSON format which is very common to use JWT.

Token-Based
Authentication.png

  • From the Auth Server side, you will need several routes that allow clients to do the following.

    • Create credentials : let the users create a new account.
    • Login : provides the users with access token and refresh token.
    • Refresh token : get a new access token if the previous token has expired.
    • Logout : invalidate token or delete recorded token on client side.
  • User credentials can be created using a combination of username and password like traditional authentication. The credentials need to be encoded from the client side and be decoded on the server side. Using Basic Authentication and Base64 encoding will do the job. When a user makes a POST request to create new credentials, the Auth Server will store it in the database.

  • When users try to login with another POST request with the Basic Authentication credential, both access token and refresh token will be returned by the Auth Server.

  • In order to start interacting with the Resource Server, the client will need this access token by inserting it into the Authorization header with ‘Bearer {access token}’ when the client sends a request to the Resource Server.

  • Once the Resource Server receives the client’s request, it confirms the verifies and allows or disallows access to the information.

At this point, you might be wondering, how can the Resource Server know if the token is valid or not when the both servers are separated from each other? The answer is to use the same Access Token Secret and Refresh Token Secret on both of them. As mentioned earlier, both secrets (256-bit-secret) are then used to generate tokens on the Auth Server and authorized users on the Resource Server.

If you are making an application that follows microservices architecture instead of a monolith, each running service should have both secrets to verify the users.

Developers can choose to either put user tokens on the client side using local storage, cookies, or session storage. Each has its own advantages and disadvantages. For example, storage using session storage would be very good from a security standpoint.

As a tradeoff, it will only be retained during the current session and automatically cleared once the user closes the browser. Thus requiring the client to ask for a new access token every time the user wants to use the service may burden the server in the long run.

  • The access token time-to-live also needs to be specified for security reasons. Ideally, in case the token is lost or stolen, it will be invalid within a period of time. The registered users need to make another request to receive a new token from the Auth Server.

  • When the user logs out, the related JWT record on the client side will be deleted so the user needs to re-login to get a new access token and refresh token.

The advantages of JWT

Statelessness & Scalability

Traditional auth will require a session maintained by the server so that both parties can interact. This makes traditional auth stateful. This is different from token-based authentication, where interaction is carried out with a token. No session is needed to maintain connection between two parties. It makes token-based authentication stateless.

In terms of scalability, the Auth Server does not need to maintain sessions continuously which may burden the server. This is especially the case when many users are conducting sessions at once. By using token based authentication, this can be avoided and way better approach for scalability.

Mobile and IoT (Internet of Things)

Both mobile and various and IoT are often not friendly when it comes to cookies or other storage modes from the client side. This is usually as a result of these two kinds of devices often interacting with the server without using a browser. For example, in IoT devices, tokens are stored locally whether in memory or local disk.

Improved Security & Better User Experience

Ideally, both access tokens and refresh tokens have an expiration date. Access tokens usually have a much shorter time span (short-lived) than refresh tokens (long-lived).

As the main authorization token, the access token will be very vulnerable to theft. It is also stored on the client side, which may be disastrous if not properly handled. Therefore, the active period may only last for a few minutes or a few hours. In contrast to refresh tokens, the ideal time frame can last longer, ranging from days to weeks. That way, users don’t need to request login too often to generate new tokens.

However, this expiration time can be adjusted depending on the level of urgency of the data being transacted.

Conclusion

Currently JWT has been used massively in various applications and websites. Its application has covered various programming languages and has been adapted by various frameworks. However, this technology is not without loopholes. There are still many known attacks targeting the token-based authentication such as token side jacking. In another case, the attacker can simply exploit the vulnerabilities made by the developer.