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 нет готовых библиотек, так как все это достаточно легко делается вручную.

Рекомендуемые программы

Завершено

0 / 15