Creating and Verifying JWTs
Creating JWTsβ
Steps to Create a JWT:
-
Define the Header:
- The header typically consists of two parts: the type of the token (which is JWT) and the signing algorithm being used (e.g., HMAC SHA256 or RSA).
-
Define the Payload:
- The payload contains the claims. These claims can be registered claims (like
iss
,exp
, etc.), public claims, or private claims.
- The payload contains the claims. These claims can be registered claims (like
-
Encode the Header and Payload:
- Both the header and the payload are JSON objects that need to be base64Url encoded.
-
Create the Signature:
- The signature is created by taking the encoded header and payload, a secret key (or private key if using RSA/ECDSA), and the algorithm specified in the header to sign that data.
-
Combine All Parts:
- The final JWT is formed by concatenating the base64Url encoded header, payload, and signature with dots (
.
) in between.
- The final JWT is formed by concatenating the base64Url encoded header, payload, and signature with dots (
Encoding the Header and Payload:
-
Header (JSON):
{
"alg": "HS256",
"typ": "JWT"
} -
Payload (JSON):
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
} -
Base64Url encoding of header:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
-
Base64Url encoding of payload:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0
Signing the Token:
- Create the signature by combining the encoded header, payload, and a secret key using the algorithm specified (e.g., HMAC SHA256):
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
) - Example signature:
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Final JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Verifying JWTsβ
Steps to Verify a JWT:
-
Extract the Components:
- Split the JWT into its three parts: header, payload, and signature.
-
Decode the Header and Payload:
- Base64Url decode the header and payload to get the original JSON objects.
-
Validate the Signature:
- Recreate the signature using the same method as when the JWT was created, using the header and payload, and compare it with the received signature.
-
Check the Claims:
- Verify the claims in the payload, such as
exp
(expiration time),nbf
(not before), andiat
(issued at).
- Verify the claims in the payload, such as
Validating the Signature:
- Recreate the signature using the received encoded header and payload and the secret key:
const validSignature = HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
);
if (validSignature !== receivedSignature) {
throw new Error('Invalid signature');
}
Checking the Claims:
-
Check the expiration time (
exp
):const currentTime = Math.floor(Date.now() / 1000);
if (payload.exp && currentTime > payload.exp) {
throw new Error('Token expired');
} -
Check the not before (
nbf
) and issued at (iat
) claims:if (payload.nbf && currentTime < payload.nbf) {
throw new Error('Token not active yet');
}
if (payload.iat && currentTime < payload.iat) {
throw new Error('Token issued in the future');
}