JWT Implementation with jsonwebtoken

Understanding the Problem

We need to create a complete JWT workflow including:

Devising a Plan

  1. Set up environment and import required packages
  2. Create a JWT with our email and expiration
  3. Implement payload decoding
  4. Implement signature verification
  5. Add error handling for invalid cases

Complete Solution

File Location: app.js

// configure environment - DO NOT MODIFY
require('dotenv').config();

// Import package
const jwt = require('jsonwebtoken');

// Your email address
const EMAIL = 'your.email@example.com';
const SECRET_KEY = process.env.SECRET_KEY;

// 1. Sign (create) a JWT containing your email address
let token; // DO NOT MODIFY! Re-assign the token variable below.

token = jwt.sign(
    { email: EMAIL },    // payload
    SECRET_KEY,         // secret key
    { expiresIn: '1h' } // options - token expires in 1 hour
);

// See the JWT in the console - DO NOT MODIFY
console.log('JWT:', token);

// 2. Decode a JWT Payload
let payload; // DO NOT MODIFY! Re-assign the payload variable below.

payload = jwt.decode(token);

// See the decoded payload in the console - DO NOT MODIFY
console.log('Payload:', payload);

// 3. Verify a JWT
let verifiedPayload; // DO NOT MODIFY! Re-assign the verifiedPayload variable below.

verifiedPayload = jwt.verify(token, SECRET_KEY);

// See the verified payload in the console - DO NOT MODIFY
console.log('Verified Payload:', verifiedPayload);

// (Optional) Bonus: Catch Error With Invalid Signature
try {
    const invalidSecret = 'wrong_secret';
    const invalidPayload = jwt.verify(token, invalidSecret);
    console.log('This should not print:', invalidPayload);
} catch (err) {
    console.log('Invalid Signature Error:', err.message);
}

// (Optional) Bonus: Catch Error With Expired Token
// Create a token that expires in 1 second
const quickToken = jwt.sign(
    { email: EMAIL },
    SECRET_KEY,
    { expiresIn: '1s' }
);

setTimeout(() => {
    try {
        const expiredPayload = jwt.verify(quickToken, SECRET_KEY);
        console.log('This should not print:', expiredPayload);
    } catch (err) {
        console.log('Expired Token Error:', err.message);
    }
}, 2000); // Wait 2 seconds to verify

Expected Input/Output

Success Cases:

JWT: eyJhbGciOiJIUzI1NiIs...
Payload: { email: 'your.email@example.com', iat: 1645577433, exp: 1645581033 }
Verified Payload: { email: 'your.email@example.com', iat: 1645577433, exp: 1645581033 }

Error Cases:

Invalid Signature Error: invalid signature
Expired Token Error: jwt expired

Step by Step Implementation

Step 1: Setup Environment

Step 2: JWT Creation (Signing)

The jwt.sign() method takes three parameters:

Step 3: JWT Decoding

jwt.decode() simply decodes the JWT without verifying:

Step 4: JWT Verification

jwt.verify() decodes and verifies the JWT:

Testing the Implementation

The provided tests verify:

  1. JWT Structure:
  2. Decoding:
  3. Verification:

Common Mistakes to Avoid

Security Best Practices

Further Learning