JWT tokens in TypeScript: a complete guide
JSON Web Token (JWT) is an open standard (RFC 7519) for creating access tokens based on the JSON format. JWT is widely used for authentication and information exchange between a client and a server. In this article, we will thoroughly examine how to work with JWT tokens in TypeScript using popular libraries and best practices.
What is JWT?
JWT consists of three parts separated by dots:
- Header — contains information about the token type and the signing algorithm
- Payload — contains data (claims) such as user ID, role, expiration time
- Signature — created from the header, payload, and secret key
A typical JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cInstalling libraries for working with JWT in TypeScript
To work with JWT in TypeScript, we will use the jsonwebtoken library along with the types @types/jsonwebtoken.
npm install jsonwebtokennpm install --save-dev @types/jsonwebtokenCreating a JWT token in TypeScript
Let's look at an example of creating a JWT token with a typed payload:
import jwt from 'jsonwebtoken';
// Define the interface for the payloadinterface TokenPayload { userId: string; email: string; role: 'user' | 'admin';}
// Secret key (in a real project, store it in .env)const JWT_SECRET = 'your-super-secret-key';
// Create a tokenfunction generateToken(payload: TokenPayload): string { return jwt.sign(payload, JWT_SECRET, { expiresIn: '1h', // token is valid for 1 hour issuer: 'pythonlib.ru', subject: payload.userId });}
// Example usageconst userPayload: TokenPayload = { userId: '12345', email: 'user@example.com', role: 'user'};
const token = generateToken(userPayload);console.log('Generated token:', token);Verification and decoding of JWT
To verify the authenticity of the token and extract data, use the following code:
import jwt, { JwtPayload, VerifyErrors } from 'jsonwebtoken';
interface DecodedToken extends JwtPayload { userId: string; email: string; role: 'user' | 'admin';}
function verifyToken(token: string): DecodedToken | null { try { const decoded = jwt.verify(token, JWT_SECRET) as DecodedToken; return decoded; } catch (error) { if (error instanceof jwt.TokenExpiredError) { console.error('Token expired'); } else if (error instanceof jwt.JsonWebTokenError) { console.error('Invalid token'); } else { console.error('Verification error:', error); } return null; }}
// Verify the tokenconst decoded = verifyToken(token);if (decoded) { console.log('Token data:', decoded); console.log('User role:', decoded.role);}Middleware for Express.js with TypeScript
Integrate JWT verification into Express middleware with full typing:
import { Request, Response, NextFunction } from 'express';import jwt from 'jsonwebtoken';
// Extend the Request interface to store user datainterface AuthRequest extends Request { user?: { userId: string; email: string; role: 'user' | 'admin'; };}
function authMiddleware(req: AuthRequest, res: Response, next: NextFunction): void { const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) { res.status(401).json({ message: 'To