Зарегистрируйтесь, чтобы продолжить обучение

Авторизация JS: REST API (Fastify)

Авторизация это процесс проверки допустимости выполнения какого-то действия. Например, в нашем проекте редактировать курс может только его автор. Как правильно реализовать авторизацию?

Авторизация это отдельный от валидации процесс, который происходит после проверки структуры входных данных, но перед валидацией бизнес-правил:

  • Fastify проверяет структуру запроса на базе JSON Schema
  • В обработчике выполняется авторизация: можно ли выполнять это действие текущим пользователем?
  • Выполняется валидация входных данных по бизнес-правилам.
  • Основная логика выполняется здесь.

Авторизация выглядит как проверка в обработчике, которая приводит к двум исходам:

  • Если все хорошо, то ничего не делаем, код выполняется дальше.
  • Если проверка не прошла, то возвращаем 403.

Рассмотрим самый простой вариант, когда проверка выполняется в обработчике напрямую. Ниже проверяется, что редактировать курс может только его автор:

fastify.patch(
  '/courses/:id',
  {
    onRequest: [fastify.authenticate],
    schema: schema['/courses/{id}'].PATCH.args.properties,
  },
  async (request) => {
    const course = await db.query.courses.findFirst({
      where: eq(schemas.courses.id, request.params.id),
    })
    fastify.assert(course, 404)

    // Авторизация
    // Проверяем что редактировать курс может только его автор
    fastify.assert.equal(request.user.id, course.creatorId, 403)

    await db.update(schemas.courses)
      .set(request.body)
      .where(eq(schemas.courses.id, request.params.id))

    return { id: request.params.id }
  },
)

Здесь мы используем встроенный в Fastify assert.equals() и передаем последним параметром код ответа 403.

С ростом сложности проекта, такие проверки выносят в отдельные сущности называемые Policy и затем их используют в нужных обработчиках. Это позволяет сократить дублирование, если одна и та же проверка встречается в разных местах.

// policies/CoursePolicy.js
export default class CoursePolicy {
  canShowIndex(creatorId, user) {
    // Проверка
  }
}

Сами политки могут быть обычными функциями, принимающими на вход необходимые данные и выполняющими внутри проверку. Для такой задачи в экосистеме Fastify и JS нет готовых библиотек, так как все это достаточно легко делается вручную.


Самостоятельная работа

  1. Добавьте в авторизацию в приложение
  2. Доработайте маршруты курсов так, чтобы при создании курса автоматически указывался автором пользователь, который выполняет запрос. Добавьте проверку в редактирование и удаление курса, чтобы эти операции мог выполнять только автор курса. Доработайте по такому же принципу маршруты уроков. Автором урока будет считаться автор курса, к которому прикреплен текущий урок
  3. Запушьте изменения в репозиторий

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff