Authorization and Authentication in TypeScript: A Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Authorization and Authentication in TypeScript: From Theory to Practice



In modern web development, application security is a cornerstone. TypeScript, as a strictly typed superset of JavaScript, provides powerful tools for building reliable systems for authentication (verifying user identity) and authorization (verifying access rights). In this article, we will cover key concepts, popular libraries, and write a working example in TypeScript.



Basic Concepts: Authentication vs Authorization



These terms are often confused. Let's clearly distinguish them:

  • Authentication — the process of verifying who you are. For example, logging in with a username and password or through a third-party service (Google, GitHub).
  • Authorization — the process of verifying what you are allowed to do. For example, accessing the admin panel or the ability to delete posts.


In TypeScript, these processes are implemented through middleware (intermediate handlers) that check tokens or sessions before executing a request.



Popular Libraries for TypeScript



For implementing authorization and authentication in TypeScript projects, the following are most commonly used:

  • jsonwebtoken — working with JWT (JSON Web Tokens).
  • bcrypt — password hashing.
  • passport (with types @types/passport) — flexible middleware for Express.
  • express-session — server-side session management.
  • crypto — built-in Node.js module for working with hashes.


Practical Example: JWT Authentication in TypeScript



Let's look at creating a simple REST API with JWT authentication. The example will use Express + TypeScript.



Step 1. Installing Dependencies

npm install express jsonwebtoken bcrypt dotenvnpm install -D typescript @types/express @types/jsonwebtoken @types/bcrypt ts-node nodemon


Step 2. TypeScript Configuration (tsconfig.json)

{  "compilerOptions": {    "target": "ES2020",    "module": "commonjs",    "outDir": "./dist",    "rootDir": "./src",    "strict": true,    "esModuleInterop": true  }}


Step 3. Creating Authentication Middleware

// src/middleware/auth.tsimport { Request, Response, NextFunction } from 'express';import jwt from 'jsonwebtoken';

interface UserPayload { id: string; email: string;}

// Extend the Request interface to store user datadeclare global { namespace Express { interface Request { user?: UserPayload; } }}

export const authenticate = ( req: Request, res: Response, next: NextFunction): void => { const authHeader = req.headers.authorization;

if (!authHeader || !authHeader.startsWith('Bearer ')) { res.status(401).json({ message: 'Token not provided' }); return; }

const token = authHeader.split(' ')[1];

try { const decoded = jwt.verify( token, process.env.JWT_SECRET || 'default_secret' ) as UserPayload; req.user = decoded; next(); } catch (error) { res.status(401).json({ message: 'Invalid token' }); }};


Step 4. Role-Based Authorization Middleware

// src/middleware/authorize.tsimport { Request, Response, NextFunction } from 'express';

export const authorize = (...allowedRoles: string[]) => { return (req: Request, res: Response, next: NextFunction): void => { // Assume the role is stored in req.user after authentication const userRole = (req as any).user?.role || 'user';

if (!allowedRoles.includes(userRole)) { res.status(403).json({ message: 'Access denied' });

Recommendations