Как вы реализуете проверку JWT-токена в Node.js приложении?

Ответ

В Node.js приложениях я обычно использую библиотеку jsonwebtoken для верификации JWT. Вот типичная реализация middleware для Express.js:

const jwt = require('jsonwebtoken');
const { JWT_SECRET } = process.env; // Секрет хранится в переменных окружения

// Middleware для проверки токена
const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // Извлекаем токен из 'Bearer <token>'

  if (!token) {
    return res.status(401).json({ error: 'Access token is required' });
  }

  jwt.verify(token, JWT_SECRET, (err, decoded) => {
    if (err) {
      // Детализируем ошибку для клиента
      let errorMessage = 'Invalid token';
      if (err.name === 'TokenExpiredError') {
        errorMessage = 'Token has expired';
      } else if (err.name === 'JsonWebTokenError') {
        errorMessage = 'Malformed token';
      }
      return res.status(403).json({ error: errorMessage });
    }

    // Если токен валиден, добавляем данные из payload в объект запроса
    req.user = decoded; // Обычно здесь id, email, roles
    next(); // Передаём управление следующему обработчику
  });
};

// Использование в роуте
app.get('/api/profile', authenticateToken, (req, res) => {
  // req.user теперь доступен
  res.json({ profile: req.user });
});

Ключевые моменты реализации:

  • Секретный ключ (JWT_SECRET) никогда не хардкодится, а берётся из переменных окружения.
  • Алгоритм подписи явно указывается при создании токена (например, HS256).
  • Обработка ошибок детализирована: отдельно обрабатываются просроченные и невалидные токены.
  • Для повышения безопасности в production можно добавить проверку списка отозванных токенов (blacklist) или использовать более сложные стратегии с refresh-токенами.

Ответ 18+ 🔞

Блин, ну смотри, тут история про то, как заставить твой сервер не пускать всяких левых чуваков. Представь, что у тебя есть секретный клуб, а на входе — здоровенный вышибала, который проверяет пропуска. Вот JWT — это и есть такой цифровой пропуск, а jsonwebtoken — это наш вышибала, только в коде.

Вот как это обычно выглядит, ёпта:

const jwt = require('jsonwebtoken');
const { JWT_SECRET } = process.env; // Секрет хранится в переменных окружения

// Middleware для проверки токена
const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // Извлекаем токен из 'Bearer <token>'

  if (!token) {
    return res.status(401).json({ error: 'Access token is required' });
  }

  jwt.verify(token, JWT_SECRET, (err, decoded) => {
    if (err) {
      // Детализируем ошибку для клиента
      let errorMessage = 'Invalid token';
      if (err.name === 'TokenExpiredError') {
        errorMessage = 'Token has expired';
      } else if (err.name === 'JsonWebTokenError') {
        errorMessage = 'Malformed token';
      }
      return res.status(403).json({ error: errorMessage });
    }

    // Если токен валиден, добавляем данные из payload в объект запроса
    req.user = decoded; // Обычно здесь id, email, roles
    next(); // Передаём управление следующему обработчику
  });
};

// Использование в роуте
app.get('/api/profile', authenticateToken, (req, res) => {
  // req.user теперь доступен
  res.json({ profile: req.user });
});

А теперь, блядь, разжёвываю, как для себя любимого.

Секретный ключ (JWT_SECRET) — это твоя главная тайна, типа пароля от жены. Никогда, слышишь, НИКОГДА не пиши его прямо в коде, как какой-нибудь распиздяй. Вынеси в переменные окружения, спрячь подальше, чтоб даже кот сука собака не нашёл. Иначе будет вам хиросима и нигерсраки, когда какой-нибудь пидарас шерстяной его утянет.

Алгоритм подписи — это как печать на том самом пропуске. Когда ты токен создаёшь, явно указывай, например, HS256. Не оставляй это на откуп библиотеке, а то она может выбрать какую-нибудь слабую хрень, и твоя безопасность накроется медным тазом.

Обработка ошибок — вот тут многие лажают, блядь. Нельзя просто написать invalid token и послать нахуй. Надо объяснить челу, в чём конкретно его косяк: то ли пропуск просрочен (TokenExpiredError), то ли он его в микроволновке пожевал и он кривой стал (JsonWebTokenError). Клиенту же надо понимать, что делать — новый токен запросить или перелогиниться.

И главное, чувак, помни: этот middleware — всего лишь базовый забор. Для серьёзных проектов этого мало. Надо думать про чёрные списки отозванных токенов (blacklist), про refresh-токены, чтобы пользователей каждый час не перелогинивать. А то без этого твоя аутентификация — это пизда рулю, честно.