logo
eng-flag

JWT (JSON Web Token) Cheat Sheet

Table of Contents

  1. Introduction to JWT
  2. JWT Structure
  3. JWT in Node.js
  4. Creating JWTs
  5. Verifying JWTs
  6. JWT Best Practices
  7. Common Use Cases
  8. Security Considerations
  9. Troubleshooting

Introduction to JWT

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. JWTs are commonly used for authentication and information exchange in web development.

Key features of JWT:

  • Compact: Can be sent through URL, POST parameter, or inside an HTTP header
  • Self-contained: Contains information about the user and eliminates the need to query the database multiple times
  • Digitally signed: Information can be verified and trusted

JWT Structure

A JWT typically looks like this:

xxxxx.yyyyy.zzzzz

It consists of three parts separated by dots (.).

  1. Header
  2. Payload
  3. Signature

The header typically consists of two parts: the type of the token (JWT) and the signing algorithm being used (e.g., HMAC SHA256 or RSA).

Example:

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

The payload contains claims. Claims are statements about the user and additional metadata.

Example:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022
}

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 changed along the way.

JWT in Node.js

To work with JWTs in Node.js, we'll use the jsonwebtoken package.

Install it using npm:

npm install jsonwebtoken

Creating JWTs

Here's how to create a JWT in Node.js:

const jwt = require('jsonwebtoken');

const payload = {
  sub: '1234567890',
  name: 'John Doe',
  admin: true
};

const secretKey = 'your-secret-key';

const token = jwt.sign(payload, secretKey, { expiresIn: '1h' });

console.log(token);

This will generate a token that expires in 1 hour.

Verifying JWTs

To verify a JWT:

const jwt = require('jsonwebtoken');

const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; // Your JWT here
const secretKey = 'your-secret-key';

try {
  const decoded = jwt.verify(token, secretKey);
  console.log(decoded);
} catch(err) {
  console.error('Invalid token:', err.message);
}

JWT Best Practices

  1. Keep it secret: Never share your secret key
  2. Use HTTPS: Always use HTTPS to prevent man-in-the-middle attacks
  3. Expiration time: Set a reasonable expiration time for your tokens
  4. Don't store sensitive data: Avoid storing sensitive information in the payload
  5. Use strong secret keys: Use a strong, unique secret key for signing tokens

Common Use Cases

1. Authentication

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

app.post('/login', (req, res) => {
  // Verify user credentials
  const user = { id: 1, username: 'john' };
  
  const token = jwt.sign({ userId: user.id }, 'secret-key', { expiresIn: '1h' });
  
  res.json({ token });
});

app.get('/protected', authenticateToken, (req, res) => {
  res.json({ message: 'Protected route accessed successfully' });
});

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  
  if (!token) return res.sendStatus(401);
  
  jwt.verify(token, 'secret-key', (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}

app.listen(3000, () => console.log('Server running on port 3000'));

2. Information Exchange

const jwt = require('jsonwebtoken');

// Server A: Creating a token with user information
const userInfo = {
  id: 123,
  name: 'Alice',
  role: 'admin'
};

const token = jwt.sign(userInfo, 'shared-secret-key');

// Send this token to Server B

// Server B: Verifying and using the token
try {
  const decoded = jwt.verify(token, 'shared-secret-key');
  console.log('User info received:', decoded);
  // Use the user info to perform actions
} catch(err) {
  console.error('Invalid token:', err.message);
}

Security Considerations

  1. Token storage: Store tokens securely (e.g., in HttpOnly cookies)
  2. Token revocation: Implement a strategy to revoke tokens if needed
  3. Refresh tokens: Use refresh tokens for long-lived sessions
  4. Payload size: Keep the payload small to reduce overhead
  5. Algorithm choice: Use strong algorithms like RS256 for production

Example of using refresh tokens:

const jwt = require('jsonwebtoken');

function generateTokens(userId) {
  const accessToken = jwt.sign({ userId }, 'access-secret', { expiresIn: '15m' });
  const refreshToken = jwt.sign({ userId }, 'refresh-secret', { expiresIn: '7d' });
  return { accessToken, refreshToken };
}

function refreshAccessToken(refreshToken) {
  try {
    const decoded = jwt.verify(refreshToken, 'refresh-secret');
    const accessToken = jwt.sign({ userId: decoded.userId }, 'access-secret', { expiresIn: '15m' });
    return accessToken;
  } catch(err) {
    throw new Error('Invalid refresh token');
  }
}

// Usage
const { accessToken, refreshToken } = generateTokens(123);

// When access token expires, use refresh token to get a new one
const newAccessToken = refreshAccessToken(refreshToken);

Troubleshooting

  1. "jwt malformed": Ensure the token is properly formatted (header.payload.signature)
  2. "invalid signature": Check if the correct secret key is being used
  3. "jwt expired": The token has passed its expiration time, generate a new one
  4. "invalid token": The token might be tampered with or incorrectly constructed

Example of handling common errors:

const jwt = require('jsonwebtoken');

function verifyToken(token) {
  try {
    return jwt.verify(token, 'your-secret-key');
  } catch(err) {
    if (err instanceof jwt.JsonWebTokenError) {
      // JWT is invalid
      console.error('Invalid JWT:', err.message);
    } else if (err instanceof jwt.TokenExpiredError) {
      // JWT has expired
      console.error('JWT has expired:', err.message);
    } else {
      // Other error
      console.error('Error verifying JWT:', err.message);
    }
    return null;
  }
}

// Usage
const result = verifyToken('your-token-here');
if (result) {
  console.log('Token is valid:', result);
} else {
  console.log('Token verification failed');
}

2024 © All rights reserved - buraxta.com