Published on

JSON Web Tokens. What, why, and how

Authors
  • avatar
    Name
    Cristian Pique
    LinkedIn

Introduction

JSON Web Tokens (JWTs) are a popular way of representing claims between two parties. They are a compact, URL-safe means of representing a set of claims that can be transferred between two parties. JWTs are used extensively in web applications, particularly in the context of authentication and authorization.

In this article, we will explore JWTs in more detail, including how they are used, some examples of their usage, and their advantages and disadvantages. Before moving forward, it is important to mention what claims are and why they are important.

In the context of JSON Web Tokens, a claim is a piece of information asserted about the JWT subject, which can be a user or an entity. Claims are used to represent information about the JWT, such as its issuer, expiration time, and other attributes that can be used to control access to resources or to make authorization decisions.

Claims in JWT are important because they allow for secure and flexible communication between two parties. By including claims in a JWT, the issuer can assert the identity of the user or entity, as well as any attributes or permissions associated with that user or entity.

For example, a JWT claim can be used to specify that a user has access to a specific resource or service, such as a certain API endpoint or a particular database. This information can be used by the server or application to grant or deny access to the requested resource, based on the user's permissions and other factors.

Usage

JWTs consist of three parts separated by dots: a header, a payload, and a signature. The header contains metadata about the token, such as the algorithm used to sign it. The payload contains the claims, which are statements about an entity (typically the user) and additional data. The signature is used to verify that the sender of the JWT is who it says it is and to ensure that the message wasn't changed along the way.

JWTs are typically used in one of two ways: as a way of storing user information in a stateless way, or as a way of securely transmitting information between two parties.

In the first use case, JWTs are often used as part of a stateless authentication system. In this scenario, when a user logs in, the server generates a JWT containing the user's ID, username, and any other relevant information. The client stores this JWT in local storage or a cookie, and includes it in the headers of all subsequent requests to the server. The server can then decode the JWT to retrieve the user's information and authenticate the request.

In the second use case, JWTs are often used as a way of securely transmitting information between two parties. For example, a client might send a request to a server to perform a sensitive operation, such as transferring funds between accounts. The server could generate a JWT containing the request parameters and send it to the client. The client would then include this JWT in the headers of a subsequent request to the server, which would use the JWT to verify that the request is valid and authorized.

The client needs to send the JWT in the Authorization header, preferably as a Bearer token. The payload can include expiration and not-before dates. It also worth mentioning that JWTs can be used in combination with other authentication mechanisms, such as OAuth2 or OpenID Connect.

Examples

Here is an example of how to encode and decode a JWT using JavaScript:

const jwt = require('jsonwebtoken');

// Create a token
const token = jwt.sign({ username: 'john.doe' }, 'secret');

// Verify the token
try {
  const decoded = jwt.verify(token, 'secret');
  console.log(decoded.username); // 'john.doe'
} catch (err) {
  console.log(err.message);
}

In this example, we are using the jsonwebtoken library to create and verify a JWT. We are encoding a simple payload containing a username and a secret key, and then decoding the JWT to retrieve the username.

Here is an example of how to encode and decode a JWT using C#:

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;

// Create a token
var claims = new[] { new Claim("username", "john.doe") };
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("secret"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
    claims: claims,
    expires: DateTime.Now.AddMinutes(30),
    signingCredentials: creds
);

// Encode the token
var encodedToken = new JwtSecurityTokenHandler().WriteToken(token);

// Decode the token
try
{
    var decodedToken = new JwtSecurityTokenHandler().ValidateToken(
        encodedToken,
        new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = key,
            ValidateIssuer = false,
            ValidateAudience = false
        },
        out var validatedToken
    );
    Console.WriteLine(decodedToken.Claims.First(claim => claim.Type == "username").Value);
}
catch (SecurityTokenException ex)
{
Console.WriteLine(ex.Message);
}

In this example, we are using the System.IdentityModel.Tokens.Jwt library to create and verify a JWT. We are encoding a simple payload containing a username and a secret key, and then decoding the JWT to retrieve the username. The secret key used to sign JWTs should be kept secret and not shared with unauthorized parties.

Conclusion

JSON Web Tokens (JWTs) are a popular way of representing claims between two parties. They are used extensively in web applications, particularly in the context of authentication and authorization. JWTs are a compact, URL-safe means of representing a set of claims that can be transferred between two parties. They are typically used in one of two ways: as a way of storing user information in a stateless way, or as a way of securely transmitting information between two parties. JWTs offer several advantages, including statelessness, scalability, and flexibility. However, they also have some disadvantages, including the need to securely store the secret key used to sign the tokens, and the potential for tokens to be stolen or compromised. JWTs are not appropriate for all use cases and that developers should carefully consider the security implications of using them. Overall, JWTs are a useful tool for web developers, but they should be used with caution and careful consideration of their security implications.