Авторизация это процесс проверки допустимости выполнения какого-то действия. Например, в нашем проекте редактировать курс может только его автор. Как правильно реализовать авторизацию?
Авторизация это отдельный от валидации процесс, который происходит после проверки структуры входных данных, но перед валидацией бизнес-правил:
- 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 нет готовых библиотек, так как все это достаточно легко делается вручную.
Самостоятельная работа
- Добавьте в авторизацию в приложение
- Доработайте маршруты курсов так, чтобы при создании курса автоматически указывался автором пользователь, который выполняет запрос. Добавьте проверку в редактирование и удаление курса, чтобы эти операции мог выполнять только автор курса. Доработайте по такому же принципу маршруты уроков. Автором урока будет считаться автор курса, к которому прикреплен текущий урок
- Запушьте изменения в репозиторий
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.