Авторизация и аутентификация в TypeScript: полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Авторизация и аутентификация в TypeScript: от теории к практике

В современной веб-разработке безопасность приложений — краеугольный камень. TypeScript, как строго типизированная надстройка над JavaScript, предоставляет мощные инструменты для построения надёжных систем аутентификации (проверка личности пользователя) и авторизации (проверка прав доступа). В этой статье мы разберём ключевые концепции, популярные библиотеки и напишем рабочий пример на TypeScript.

Основные понятия: аутентификация vs авторизация

Часто эти термины путают. Давайте чётко разделим:

  • Аутентификация (Authentication) — процесс проверки, кто вы. Например, вход по логину и паролю или через сторонний сервис (Google, GitHub).
  • Авторизация (Authorization) — процесс проверки, что вы можете делать. Например, доступ к админ-панели или возможность удалять посты.

В TypeScript эти процессы реализуются через middleware (промежуточные обработчики), которые проверяют токены или сессии перед выполнением запроса.

Популярные библиотеки для TypeScript

Для реализации авторизации и аутентификации в TypeScript-проектах чаще всего используют:

  • jsonwebtoken — работа с JWT (JSON Web Tokens).
  • bcrypt — хеширование паролей.
  • passport (с типами @types/passport) — гибкий middleware для Express.
  • express-session — управление сессиями на сервере.
  • crypto — встроенный модуль Node.js для работы с хешами.

Практический пример: JWT-аутентификация на TypeScript

Рассмотрим создание простого REST API с аутентификацией через JWT. Пример будет на Express + TypeScript.

Шаг 1. Установка зависимостей

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

Шаг 2. Конфигурация TypeScript (tsconfig.json)

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

Шаг 3. Создание middleware для аутентификации

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

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

// Расширяем интерфейс Request для хранения данных пользователя
declare 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: 'Токен не предоставлен' });
    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: 'Невалидный токен' });
  }
};

Шаг 4. Middleware для авторизации по ролям

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

export const authorize = (...allowedRoles: string[]) => {
  return (req: Request, res: Response, next: NextFunction): void => {
    // Предполагаем, что роль хранится в req.user после аутентификации
    const userRole = (req as any).user?.role || 'user';

    if (!allowedRoles.includes(userRole)) {
      res.status(403).json({ message: 'Доступ запрещён' });
      return;
    }
    next();
  };
};

Шаг 5. Роуты для регистрации и входа

// src/routes/auth.ts
import { Router, Request, Response } from 'express';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';

const router = Router();

// Временное хранилище пользователей (в реальности — база данных)
const users: Array<{ id: string; email: string; password: string; role: string }> = [];

// Регистрация
router.post('/register', async (req: Request, res: Response) => {
  const { email, password, role } = req.body;

  // Проверка, существует ли пользователь
  const existingUser = users.find(u => u.email === email);
  if (existingUser) {
    return res.status(400).json({ message: 'Пользователь                    

Рекомендаций