JSON Web Token (JWT)
Adrián Bailador
Posted on March 14, 2024
1. What is JSON Web Token
JSON Web Token (JWT) is an open standard based on JSON for creating a token used to send data between applications or services, ensuring that they are valid and secure. This information can be verified and trusted because it is digitally signed.
2. When to Use JSON Web Token?
When JWT is useful:
- Authorization, the most common use. Once the user has logged in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources permitted with that token. Single Sign-On (SSO) is a widely used feature in JWT today due to its small overhead and its ease of use across different domains.
- Information exchange, JWTs are a good way to securely transmit information between parties. Because JWTs can be signed, for example, using public/private key pairs, you can be sure that senders are who they claim to be. Additionally, as the signature is computed using the header and payload, you can also verify that the content has not been tampered with.
3. How does JSON Web Token work?
In authentication, when the user successfully logs in with their credentials, a JSON Web Token will be returned. Since tokens are credentials, care must be taken to avoid security issues. In general, you should not keep tokens longer than necessary.
Each time the user wants to access a protected route or resource, the user agent must send the JWT, usually in the Authorization header using the Bearer schema.
The application or client requests authorization from the authorization server.
When authorization is granted, the authorization server returns an access token to the application.
The application uses the access token to access a protected resource (such as an API).
4. JSON Web Token Structure
A JWT is divided by dots (HEADER.PAYLOAD.SIGNATURE) into three encoded parts, a header, a payload, and a signature.
We can decode and view the content of the token using jwt.io without needing to know the key with which it was generated, although we will not be able to validate it without it.
- Header: the type of token and the algorithm used for the signature.
{
"alg": "HS256", // HS256 indicates that this token is signed using HMAC-SHA256.
"typ": "JWT"
}
- Payload: contains claims that are data about an entity (usually the user) and additional data. Information is provided as key/value pairs. Do not include sensitive data without encryption in the claims. There are 3 types of claims:
- Registered claims: predefined claims that are not mandatory. They are listed in the IANA JSON Web Token Claim Register, and their purpose is established in a standard. Examples include iss (issuer), aud (audience), exp (expiration time), sub (subject), among others.
- Public claims: can be defined at will, as they are not subject to restrictions. To prevent conflicts in the semantics of claims, it is necessary to register public claims publicly in the IANA JSON Web Token Claim Register or assign them names that cannot conflict.
- Private claims: These are custom claims created to share information between parties that agree to use them and are neither registered nor public claims. When naming them, it is important to ensure that they do not conflict with any registered or public claim.
{
"sub": "1234445670",
"name": "Adri Dev",
"admin": true
}
- Signature: is a signature that allows us to verify if the token is valid. To create the signature part, you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign it.
key = 'secret-key'
unsignedToken = base64Encode(header) + '.' + base64Encode(payload)
signature = SHA256(key, unsignedToken)
token = unsignedToken + '.' + signature
- The signature is used to verify that the message was not changed along the way and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who they say they are.
// JSON Web Token (HEADER.PAYLOAD.SIGNATURE):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpCVXJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQwws8a
5. Best Practices Using JSON Web Token
When generating tokens:
- Always issue signed tokens.
- Use strong cryptographic algorithms.
- Include expiration date and unique identifier.
- Provide value to the issuer and audience.
- Do not include sensitive data without encryption in the claims.
When validating:
- Do not accept tokens without a signature.
- Always validate header claims.
- Always validate issuer and audience.
- Store signing keys by issuer and algorithm.
Communication:
- Communication between parties with HTTPS to encrypt traffic.
6. Difference Between Authentication and Authorization
When dealing with JWT or permissions, we always think of the words authenticate and authorize.
First a brief description:
Authentication is the process of verifying the user's identity using credentials, commonly username and password.
Authorization is once we are authenticated, the process of checking that this user has the permissions to access the system.
The authorization (and authentication) process can be managed by the same server as authorization or not. For example, it is very common nowadays to delegate this authentication to services like Google or Facebook. (The typical thing we see on websites "login with Google"). and this is where OAuth comes in.
6.1. What is OAuth?
OAuth is a standard for authorization and anyone can implement it.
That is why I have mentioned that it can come from our server or from another one such as Google.
6.2. What is OAuth2?
As we can imagine, it is version 2 of the OAuth protocol, it simplifies the previous version and makes it easier to use between applications.
As mentioned above, the great advantage of using OAuth is that we delegate the authentication and authorization of our users to third-party services (such as Google or Facebook).
This functionality is very useful for many websites because they only need the username, for example, to comment on a post.
7. Differences Between JWT and OAuth
At this point, we already have a clear difference between JWT and OAuth (or OAuth2).
JWT is the format of the security token, while OAuth is the standard authorization protocol that can use JWT as a token.
In a real use case, we should not worry about how the user got that token, but when it arrives at our application, validate it, and if it is valid, process the request. However, for performing logout or logging out a user, we should use OAuth2 because JWT alone does not have the ability to "cancel the token" but it has an expiration time and the token will be valid until that time.
8. Using JWT in Microservices
When we are in the world of microservices, using JWT is very common since from the same microservice or application we go calling different services without having to log in again etc.
Let's imagine a medium-sized application where we have access to information about football, teams, players, each of them being a microservice.
At the end of the day, a microservice is an application that is completely functional by itself, so if we need certain permissions to access that information, we must be identified in the system.
But if we stop to think, it doesn't make much sense to ask the user to identify themselves 3 times, once should be enough. This is where JWT comes in.
Whether on our own server or on a third-party one, we will log in and this will return us a token. And we will use that token to consult or request information from different services.
This token that we usually receive is of the bearer token type to avoid CSRF (cross-site scripting) in our requests.
9. Advantages and Disadvantages of JSON Web Tokens
9.1. Advantages of JWT
JWT tokens are stateless, meaning they are not stored on the server-side, thus not consuming memory.
With JWT signature, we ensure its origin and validity, allowing us to trust that the request is legitimate.
The same token serves for multiple applications, which improves user experience in certain situations and certainly improves development.
9.2. Disadvantages of JWT
For me, the biggest disadvantage of JWT is that since it is a token valid for X time, if we want to logout or deny access to a token that already has it, we must wait for the validity time of the token to expire or implement a series of systems such as blacklists that add a lot of complexity to the matter. (For example, if a token has been stolen)
As I explained throughout the post, tokens are valid for X time, but what happens if the time runs out and we want to stay logged in. For this, we need to implement what is called Refresh tokens, which allow us to refresh the tokens to keep them valid.
10. Security in JSON Web Tokens
Secure Handling of Secrets
It is crucial to handle and store the secret keys used to sign the tokens securely. Some recommended practices include:
- Use of secure storage: Store secret keys in a secure location, such as environment variables or secret management systems.
- Periodic key rotation: Establish policies for rotating secret keys periodically to reduce the risk of compromise.
- Access control: Restrict access to secret keys only to those users or services that need them, using appropriate access control mechanisms.
Prevention of manipulation attacks
To protect against attacks such as token manipulation, token forgery, and identity spoofing, the following measures can be implemented:
- Thorough validation: Perform thorough validation of incoming tokens, verifying the signature and the data contained in the token.
- Signed with secure algorithms: Use robust and secure signature algorithms, such as HMAC with SHA-256 or RSA with SHA-256.
- Secure encoding: Use secure encoding to prevent injection attacks, such as Base64 URL encoding in token generation and verification.
Token Renewal
To manage token renewal and expiration effectively, consider implementing the following strategies:
- Refresh tokens: Use refresh tokens to allow clients to obtain a new access token without the need for re-authentication.
- Appropriate expiration time: Set reasonable expiration times for access and refresh tokens, balancing security with user convenience.
- Implementation of renewal policies: Define clear policies for token renewal and apply them consistently throughout the application.
11. Advanced Use Cases
Two-Factor Authentication (2FA)
Integrating JSON Web Tokens with two-factor authentication (2FA) systems can provide an additional layer of security. Some ways to do this include:
- Incorporating additional factors: Require users to provide a second factor of authentication, such as a code sent via SMS or generated by an authentication app.
- Multi-factor verification: Validate both the JWT token and the second factor of authentication before granting access to protected resources.
Session Management
Using JSON Web Tokens to manage user sessions efficiently and scalably is particularly useful in web and mobile applications. Some important considerations include:
- Session portability: Store session information in the JWT token allows users to access resources independently of the server session, simplifying scalability and distribution.
- Session persistence: Leverage the ability of JWT tokens to contain persistent session information, facilitating session management in distributed and microservices applications.
- Session revocation: Implement mechanisms to revoke JWT tokens individually or in bulk in case of security compromise or user logout.
Conclusion
JSON Web Tokens (JWT) are a versatile and powerful tool for authentication and authorization in information systems. Their ability to securely transmit data between applications and services, along with their compact structure and digital signature capability, makes them a popular choice in web and mobile application development.
This article has explored the basics of JWT, from its definition and structure to its practical implementation and advanced security considerations. Additionally, the difference between authentication and authorization has been highlighted, along with the role of OAuth and OAuth2 in the context of JWT.
By understanding the advantages and disadvantages of JWT, along with best practices for secure use, developers can make the most of this technology to ensure security and efficiency in their applications. With advanced use cases such as two-factor authentication and session management, JWT demonstrates its relevance and versatility in modern software development environments.
In summary, JWT provides a solid foundation for secure and scalable systems, and its intelligent adoption can significantly improve user experience and application security.
Posted on March 14, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.