What's JWT
JWT, or JSON Web Token, is a compact and self-contained method for securely transmitting information between two parties as a JSON object. It's commonly used in authentication and authorization mechanisms in web applications. JWTs are used to verify the identity of users and authorize them to access certain resources without requiring their credentials to be stored or transmitted repeatedly.
Key components of a JWT
A JWT consists of three key components header, payload and signature.
Header
Contains metadata about the token, such as the type of token (JWT) and the signing algorithm being used (e.g., HS256 or RS256).
Payload
Contains the claims, which are the data you want to transmit. This can include user information or any other data the token needs to carry.
Common claims include:
-
sub: Subject (user identifier)
-
iat: Issued at time (timestamp when the token was created)
-
exp: Expiration time (timestamp when the token expires)
-
Custom claims like user name, role, permissions, etc.
Signature
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 altered along the way. The signature is created by encoding the header and payload, and then signing that string using the secret or private key and the algorithm specified in the header.
JWT in practice: Generating and Verifying Tokens with HMAC (SHA-256)
In this example, I'll show how to generate and verify a JWT using HMAC with SHA-256, a symmetric signing algorithm. We'll use a shared secret for both signing and verifying the token.
The function createJWT
takes a payload (user data) and signs it using the SECRET_KEY
with HMAC SHA-256. We base64url-encode both the header and payload, then append the signature to complete the token.
When verifying the token, we decode the signature, check its integrity, and verify the expiration (exp
) claim if present.
How JWT works
The server generates a token (usually after successful login), signs it with a secret or private key, and sends it to the client.
The client typically stores the token in localStorage
(which is generally not recommended due to potential security risks) or cookies
.The token is then sent with each request to the server, allowing the server to verify its authenticity using the signing key. This process ensures that only valid tokens can access protected resources.
Key Use Cases
-
Authentication: After a user logs in, a JWT is issued. The client sends this token with each subsequent request, allowing the server to verify the user's identity without needing to log in again.
-
Authorization: JWTs can also carry information about what resources the user can access, allowing servers to restrict access based on user roles or permissions.
Conclusion
JWTs offer a robust and stateless way to handle authentication and authorization. By securely transmitting information via a compact token, JWTs enable web applications to verify user identity and permissions efficiently. The tokens are self-contained, meaning they can carry all the necessary information without requiring repetitive access to the server for session data. This results in a more scalable and performant system.
For practical implementation, it’s essential to:
-
Keep your secret key secure: In symmetric algorithms like HMAC, this key is what ensures the integrity of the token. If compromised, unauthorized users could generate valid tokens.
-
Use short expiration times: With sensitive data, short-lived tokens minimize risk if a token is stolen. When a token expires, clients can request a new one if they’re still authenticated.
-
Store tokens safely: Store JWTs securely, preferably in httpOnly cookies to prevent JavaScript access and reduce the risk of cross-site scripting (XSS) attacks.
JWTs are widely supported and compatible with many libraries and frameworks, making them a versatile choice for securing modern web applications.