PurpleSchool — курсы программирования онлайн
  • Пути
    • Frontend React разработчик
    • Frontend Vue разработчик
    • Backend разработчик Node.js
    • Fullstack разработчик React / Node.js
    • Mobile разработчик React Native
    • Backend разработчик Golang
    • Devops инженер
    • Backend разработчик Python
  • AI для кодаНовое
  • О нас
    • Отзывы
    • Реферальная программа
    • О компании
    • Контакты
  • Иконка открытия меню
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
PurpleSchool — платформа бесплатных roadmap и курсов для разработчиков
ютуб иконка
Telegram иконка
VK иконка
VK иконка
Курсы
ГлавнаяКаталог курсовFrontendBackendFullstack
Практика
КарьераПроектыPurpleПлюс
Материалы
БлогБаза знаний
Документы
Договор офертаПолитика конфиденциальностиПроверка сертификатаМиграция курсовРеферальная программа
Реквизиты
ИП Ларичев Антон АндреевичИНН 773373765379contact@purpleschool.ru

PurpleSchool © 2020 -2026 Все права защищены

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развитияВопросы для собеседований
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • PurpleSchool — курсы программирования онлайн
    • AI для кодаНовое
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    Авторизация и аутентификация в Node.js: JWT, OAuth2 и сессии

    Авторизация и аутентификация в Node.js: JWT, OAuth2 и сессии

    Аватар автора Авторизация и аутентификация в Node.js: JWT, OAuth2 и сессии

    Антон Ларичев

    Иконка календаря11 июня 2026
    Node.jsБезопасностьJWTOAuth2АутентификацияmiddleИконка уровня middle
    Картинка поста Авторизация и аутентификация в Node.js: JWT, OAuth2 и сессии

    Введение

    Аутентификация отвечает на вопрос «кто вы?», а авторизация — «что вам разрешено?». Эти два слоя часто путают, но проектируются они по-разному: первый проверяет подлинность пользователя, второй — его права. В Node.js для решения этих задач исторически сложились три подхода: серверные сессии, JWT и делегированная авторизация через OAuth2. Каждый имеет свою область применимости, и выбор зависит от модели угроз, архитектуры и удобства эксплуатации.

    В статье разберём, как реализовать каждый подход на Express, где у них слабые места и как их комбинировать. Примеры намеренно минималистичные — чтобы сосредоточиться на сути, а не на обвязке.

    Серверные сессии

    Классическая схема: сервер хранит состояние сессии (в Redis, БД или памяти), а клиенту отдаёт только идентификатор в HttpOnly-куке. Это безопасно по умолчанию: JS на клиенте к куке не достучится, отзыв сессии — это просто удаление записи в хранилище.

    import express from 'express';
    import session from 'express-session';
    import RedisStore from 'connect-redis';
    import { createClient } from 'redis';
    
    const redisClient = createClient({ url: process.env.REDIS_URL });
    await redisClient.connect();
    
    const app = express();
    app.use(express.json());
    
    app.use(session({
      store: new RedisStore({ client: redisClient }),
      secret: process.env.SESSION_SECRET,
      resave: false,
      saveUninitialized: false,
      cookie: {
        httpOnly: true,        // недоступна из JS
        secure: true,          // только по HTTPS
        sameSite: 'lax',       // защита от большинства CSRF
        maxAge: 1000 * 60 * 60 * 24 // сутки
      }
    }));
    
    app.post('/login', async (req, res) => {
      const user = await verifyCredentials(req.body.email, req.body.password);
      if (!user) return res.status(401).end();
      // сохраняем минимум данных — остальное подтянем из БД
      req.session.userId = user.id;
      res.json({ ok: true });
    });
    

    Плюсы: моментальный отзыв доступа, простая ротация, состояние всегда актуально. Минусы: нужна общая для всех инстансов сессионная БД, требуется CSRF-защита для небезопасных методов.

    JWT: токены без состояния

    JWT (JSON Web Token) — это подписанный токен, который сам содержит данные о пользователе. Сервер не хранит сессию: достаточно проверить подпись и срок действия. Удобно для распределённых API и микросервисов.

    import jwt from 'jsonwebtoken';
    
    const ACCESS_TTL = '15m';
    const REFRESH_TTL = '30d';
    
    function issueTokens(user) {
      const access = jwt.sign(
        { sub: user.id, role: user.role },
        process.env.JWT_ACCESS_SECRET,
        { expiresIn: ACCESS_TTL }
      );
      const refresh = jwt.sign(
        { sub: user.id, jti: crypto.randomUUID() },
        process.env.JWT_REFRESH_SECRET,
        { expiresIn: REFRESH_TTL }
      );
      return { access, refresh };
    }
    
    // middleware для защищённых маршрутов
    function authRequired(req, res, next) {
      const header = req.headers.authorization ?? '';
      const token = header.startsWith('Bearer ') ? header.slice(7) : null;
      if (!token) return res.status(401).end();
      try {
        req.user = jwt.verify(token, process.env.JWT_ACCESS_SECRET);
        next();
      } catch {
        res.status(401).end();
      }
    }
    

    Главное правило — короткоживущий access-токен и отдельный refresh с возможностью отзыва. Refresh-токен лучше хранить в HttpOnly-куке и записывать его jti в БД, чтобы можно было инвалидировать конкретное устройство.

    Где хранить токены на клиенте

    Хранение JWT в localStorage — частый источник XSS-уязвимостей: любой инжектированный скрипт получит доступ к токену. Безопаснее держать access-токен в памяти JS-процесса, а refresh — в HttpOnly-куке с SameSite=Strict или Lax.

    OAuth2: делегированная авторизация

    OAuth2 нужен, когда вы хотите войти через GitHub, Google или Yandex, либо предоставить сторонним приложениям ограниченный доступ к вашему API. Это протокол получения access-токена от имени пользователя без передачи его пароля.

    Для веб-приложений подходит Authorization Code Flow с PKCE. Удобнее всего реализовать его через Passport.js или специализированные библиотеки.

    import passport from 'passport';
    import { Strategy as GitHubStrategy } from 'passport-github2';
    
    passport.use(new GitHubStrategy({
      clientID: process.env.GITHUB_CLIENT_ID,
      clientSecret: process.env.GITHUB_CLIENT_SECRET,
      callbackURL: '/auth/github/callback',
      scope: ['user:email']
    }, async (accessToken, refreshToken, profile, done) => {
      // ищем пользователя или создаём нового
      const user = await upsertUserByOAuth('github', profile);
      done(null, user);
    }));
    
    app.get('/auth/github', passport.authenticate('github'));
    
    app.get('/auth/github/callback',
      passport.authenticate('github', { failureRedirect: '/login' }),
      (req, res) => {
        // после успешного входа создаём свою сессию или JWT
        req.session.userId = req.user.id;
        res.redirect('/');
      }
    );
    

    Обратите внимание: OAuth2 решает только задачу получения токена от провайдера. После колбэка вы всё равно создаёте собственную сессию или выдаёте свой JWT — провайдерский access-токен наружу не пробрасывается.

    Частые ошибки

    • Использование alg: none или слабого секрета для JWT. Подпись HS256 требует длинного случайного ключа, а лучше — пары RS256/ES256.
    • Длинный TTL у access-токена. Если токен живёт сутки, отозвать его без чёрного списка невозможно. Делайте 5–15 минут и обновляйте через refresh.
    • Хранение JWT в localStorage. Любая XSS превращается в кражу токена. Используйте HttpOnly-куки или память процесса.
    • Отсутствие CSRF-защиты для куки-сессий. SameSite=Lax помогает, но для критичных операций добавляйте CSRF-токен.
    • Доверие данным из JWT без проверки подписи. jwt.decode не проверяет подпись — всегда вызывайте jwt.verify.
    • Реализация OAuth2 вручную. Протокол кажется простым, но детали PKCE, state, nonce легко упустить. Берите проверенные библиотеки.
    • Смешение ролей в access-токене без актуализации. Если права пользователя поменялись, старый JWT всё ещё их содержит до истечения срока.

    Заключение

    Сессии, JWT и OAuth2 — не конкуренты, а инструменты с разными зонами ответственности. Для классического веб-приложения с серверным рендерингом сессии в Redis остаются самым простым и безопасным выбором. JWT раскрывают потенциал в распределённых API и мобильных клиентах, особенно в паре с refresh-токенами. OAuth2 нужен там, где требуется делегированный доступ или социальный вход.

    Выбирайте подход осознанно, опираясь на модель угроз и эксплуатационные требования, и не пренебрегайте базовыми мерами: HTTPS, HttpOnly-куки, короткие TTL, проверка подписи и валидация всех входных параметров.

    Иконка глаза1 063

    Комментарии

    0

    Постройте личный план изучения Feature-Sliced Design до уровня Middle — бесплатно!

    Feature-Sliced Design — часть карты развития Frontend

    • step100+ шагов развития
    • lessons30 бесплатных лекций
    • lessons300 бонусных рублей на счет

    Бесплатные лекции

    Лучшие курсы по теме

    изображение курса

    Angular

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.6
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Vue 3 и Pinia

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.8
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Nuxt

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга5.0
    3 999 ₽ 6 990 ₽
    Подробнее

    Похожие статьи

    Иконка аватараАнтон
    Иконка календаря27 сентября 2026
    openaiAI-инструментыDevOps+ 2middleИконка уровня middle

    Как установить Codex на Windows в России

    Установка Codex на Windows состоит из двух разных дел, и второе обычно застаёт врасплох. Сам агент ставится одной командой `npm install -g @openai/codex` и на Windows работает так же, как на macOS: пакет скачивается из npm без всяких препятствий. А вот первый же запрос к модели закончится отказом: по умолчанию Codex авторизуется через аккаунт ChatGPT, а этот путь из России закрыт — ни вход, ни оплата подписки российской картой не пройдут. Поэтому после установки нужен второй шаг: прописать Codex другой адрес модельного провайдера и ключ к нему. Ключ можно взять в [AI для кода от PurpleSchool](

    Иконка чипа0
    Иконка глаза218
    Иконка комментариев0
    Иконка аватараАнтон
    Иконка календаря24 сентября 2026
    Claude CodeAnthropicAI-инструменты+ 2middleИконка уровня middle

    Как установить Claude Code на Windows: инструкция из России

    Claude Code ставится на Windows одной командой `npm install -g @anthropic-ai/claude-code` — при условии, что в системе есть Node.js. Проблема начинается после установки: CLI поднимется, но при первом же запросе вернёт ошибку доступа, потому что API Anthropic не обслуживает запросы из России. Поэтому установка на Windows из России — это два отдельных дела: поставить сам пакет и подсунуть ему рабочий адрес API с ключом. Ниже — оба шага по порядку, с синтаксисом именно для PowerShell, а не для bash.

    Иконка чипа0
    Иконка глаза512
    Иконка комментариев0
    Иконка аватараАнтон
    Иконка календаря06 октября 2026
    Claude CodeAI-инструментыDevOps+ 2middleИконка уровня middle

    Claude Code или Cursor: что выбрать в 2026 году

    Короткий ответ: Claude Code берут, когда агент должен работать сам — в терминале, по инструкциям из репозитория, без открытого редактора; Cursor — когда нужен редактор, в котором ассистент всегда под

    Иконка чипа0
    Иконка глаза87
    Иконка комментариев0
    Иконка чипа0