Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+1 210новых вакансий за сутки·93 612вакансий открыто сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании7 266
РезюмеAIПодготовкаСтатьи
BoostТарифыBoost
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 401 кандидат открыт к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python17 126
  • Облачные технологии14 083
  • QA вакансии3 456
  • Backend вакансии2 116
  • Инженер данных1 809
  • Продакт-менеджер1 261

Разработка

  • Android1 862
  • iOS1 700
  • Fullstack вакансии990
  • AI вакансии951
  • Frontend вакансии749
  • Mobile вакансии44

По стеку

  • Go8 688
  • Java6 537
  • Node.js2 026
  • .NET1 722
  • Kotlin1 611
  • Rust1 458
  • C#710
  • PHP682
  • C++571

DevOps и инфраструктура

  • Kubernetes7 772
  • DevOps вакансии6 054
  • Linux-инфраструктура5 493
  • Terraform / IaC4 275
  • CI/CD3 239
  • Мониторинг и Observability1 790
  • SRE568
  • Кибербезопасность458

Аналитика и данные

  • Data Scientist1 143
  • Бизнес-аналитик923
  • Аналитик данных857
  • Системный аналитик152

Другие направления

  • Проджект-менеджер620
  • UI/UX дизайн147
  • Ручное тестирование14

По регионам

  • Вакансии в США44 437
  • Вакансии в Европе23 855
  • Вакансии в Канаде4 483
  • Работа в России3 904

По формату

  • Удалённые вакансии75 212
  • Релокация в США44 436
  • Гибридная работа12 388
  • Офисная работа7 083

По уровню

  • Senior вакансии42 625
  • Middle вакансии20 854
  • Junior вакансии6 721

Сейчас нанимают

Все компании
  • Wise190 вакансий
  • Rakuten189 вакансий
  • ASML166 вакансий
  • Grab137 вакансий
  • Celonis39 вакансий
  • Spotify37 вакансий
  • Adyen28 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace16 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме FastifyВсе вопросы
FastifyMiddleКодинг

Как реализовать аутентификацию в Fastify с помощью fastify-jwt или @fastify/jwt?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

@fastify/jwt регистрируется с секретом, добавляет методы app.jwt.sign() и request.jwtVerify(). Защищённые роуты вызывают request.jwtVerify() в preHandler-хуке; публичные роуты пропускают хук.

Установка

npm install @fastify/jwt

Регистрация плагина

import Fastify from 'fastify';
import jwt from '@fastify/jwt';

const app = Fastify({ logger: true });

await app.register(jwt, {
  secret: process.env.JWT_SECRET, // минимум 32 символа
  sign: {
    expiresIn: '15m', // access-token живёт 15 минут
  },
  // Для RS256 передайте { private: '...', public: '...' }
});

Декоратор authenticate

Создайте переиспользуемый декоратор, который будет применяться как preHandler на защищённых роутах:

app.decorate('authenticate', async (request, reply) => {
  try {
    await request.jwtVerify();
  } catch (err) {
    reply.code(401).send({ error: 'Unauthorized', message: err.message });
  }
});

Роуты: логин и защищённый эндпоинт

// POST /auth/login — выдача токена
app.post('/auth/login', async (request, reply) => {
  const { email, password } = request.body;

  // Проверка пользователя из БД (упрощённо)
  const user = await findUserByEmail(email);
  if (!user || !(await verifyPassword(password, user.passwordHash))) {
    return reply.code(401).send({ error: 'Invalid credentials' });
  }

  const token = app.jwt.sign(
    { sub: user.id, email: user.email, role: user.role },
    { expiresIn: '15m' }
  );

  return { accessToken: token };
});

// GET /profile — только для аутентифицированных
app.get(
  '/profile',
  { preHandler: [app.authenticate] },
  async (request) => {
    // request.user содержит декодированный payload
    const { sub, email, role } = request.user;
    return { userId: sub, email, role };
  }
);

Refresh-токены

Access-токен намеренно короткоживущий. Refresh-токен выдаётся с большим TTL и хранится в httpOnly-куке:

app.post('/auth/login', async (request, reply) => {
  const user = await authenticateUser(request.body);

  const accessToken = app.jwt.sign(
    { sub: user.id, role: user.role },
    { expiresIn: '15m' }
  );

  const refreshToken = app.jwt.sign(
    { sub: user.id, type: 'refresh' },
    { expiresIn: '7d' }
  );

  reply
    .setCookie('refreshToken', refreshToken, {
      httpOnly: true,
      secure: true,
      sameSite: 'strict',
      path: '/auth/refresh',
      maxAge: 7 * 24 * 3600,
    })
    .send({ accessToken });
});

app.post('/auth/refresh', async (request, reply) => {
  const token = request.cookies?.refreshToken;
  if (!token) return reply.code(401).send({ error: 'No refresh token' });

  try {
    const payload = app.jwt.verify(token);
    if (payload.type !== 'refresh') throw new Error('Wrong token type');

    const newAccess = app.jwt.sign(
      { sub: payload.sub },
      { expiresIn: '15m' }
    );
    return { accessToken: newAccess };
  } catch {
    return reply.code(401).send({ error: 'Invalid refresh token' });
  }
});

TypeScript: расширение типа request.user

declare module '@fastify/jwt' {
  interface FastifyJWT {
    payload: { sub: string; email: string; role: string };
    user: { sub: string; email: string; role: string };
  }
}

Подводные камни

  • Слабый секрет — строки вроде "secret" или "password" брутфорсятся мгновенно. Используйте минимум 256-битный случайный ключ (openssl rand -hex 32).
  • HS256 vs RS256 — HS256 требует хранить один секрет на всех сервисах. Если токены проверяют несколько сервисов, используйте RS256: публичный ключ можно раздать свободно.
  • Отсутствие инвалидации токенов — JWT stateless; отозвать конкретный токен без redis-списка отозванных невозможно. Планируйте механизм revoke заранее.
  • Хранение в localStorage — уязвимо к XSS. Access-токен лучше хранить в памяти JS, refresh-токен — в httpOnly-куке.
  • request.jwtVerify() проверяет только Bearer-заголовок по умолчанию — если токен приходит в куке, передайте { onlyCookie: true } или настройте extractToken.
  • Отсутствие проверки role/scope — jwtVerify лишь валидирует подпись и срок; авторизацию по роли пишите отдельно.
  • Время жизни access-токена слишком велико — токен на 24 часа сводит на нет смысл JWT при компрометации. Держите access TTL ≤15–30 минут.
  • Отладка без clock skew — если сервер и клиент имеют рассинхронизированные часы, токен может считаться истёкшим. Используйте опцию clockTolerance (например, 30 секунд).

Типичные ошибки

  • Дает общий ответ про Node.js и не называет конкретные API Fastify.
  • Не объясняет, где в lifecycle находится аутентификация через @fastify/jwt.
  • Не разделяет validation, authorization, business logic и persistence.
  • Игнорирует ошибки, лимиты входных данных, observability и тестирование.

Что проверяет интервьюер

  • Может объяснить аутентификация через @fastify/jwt на примере кода.
  • Называет ключевые API: @fastify/jwt, request.jwtVerify().
  • Использует точные API Fastify, а не вымышленные hooks/decorators/methods.
  • Видит production-риски: безопасность, отказоустойчивость, логирование и тесты.

Как вы знаете этот вопрос?

Проверить себя по теме Fastify →

Источники

  • https://github.com/fastify/fastify-jwt#readme
  • https://fastify.dev/docs/latest/Reference/Hooks/
←Предыдущий вопросЧто такое `fastify.inject()` и как он используется в тестировании?Следующий вопрос→Как реализовать CORS в Fastify с помощью `@fastify/cors`?

Связанные темы

Fastifyauthenticationauthorizationsecurity-boundaries

Частые вопросы на собеседовании

  • Что такое Fastify и каковы его основные преимущества перед Express.js?
  • Как работает система плагинов (plugin system) в Fastify? Что такое fastify-plugin и почему он нужен для инкапсуляции scope?
  • Что такое schema-based validation в Fastify и как используется JSON Schema?
  • Что такое lifecycle в Fastify? Перечислите основные hooks по порядку.