Промежуточное ПО
Хорошо, мы умеем писать контроллеры и частично можем запустить простенькую api для своих нужд. Но что, если наша api обеспечивает данными большое количество пользователей и, к некоторым данным, можно допускать только людей по условию: авторизированных или только админов, модераторов, а так же возможность предоставлять доступ с учётом чёрного списка. Это называется middleware.
Беспокоиться особо не нужно, ведь эту систему я тоже уже реализовал в пакете fastify-easy-route
Для добавления middleware вам нужно добавить 1 строку (не считая самой middleware). Открываем index.js и редактируем код добавление плагина fastify-easy-route:
// fastify.register(require('fastify-easy-route'))
fastify.register(require('fastify-easy-route'), {
path: "controllers",
middleware: 'middleware'
});
path - Параметр с помощью которого мы можем изменить название папки с контроллерами. middleware - Параметр указывающий имя файла который находится в папке module. Этот файл будет выполняться прежде чем запрос к api будет передан контроллеру. Прежде чем приступить к написанию middleware давайте добавим пару строк в наш контроллер. К примеру у нас в api будут контроллеры которые может выполнять только админ... Бан юзеров, удаление материалов, модерирование и тд. (Эти объекты могут иметь любые названия но мы укажем root и auth).
module.exports = {
method: "GET",
auth: true,
root: true,
config: { *** },
async execute(fastify, request, reply) {
***
}
}
root: ture говорит нам что этот контроллер доступен пользователю с ролью root auth: true говорит о том что пользователь должен быть авторизован. Следовательно:
// Доступ к контроллеру есть только у админа
...
auth: true,
root: true
...
//
// Доступ есть у всех, даже если пользователь не прошел проверку подписи
...
auth: false,
root: false
...
//
// Доступ есть у всех прошедших проверку подписи пользователей
...
auth: true,
root: false
...
//
При более гибкой системе доступов мы можем указать множество подобных параметров:
...
tester: true,
moderator: true,
admin: true,
creator: true,
***
...
Для чего это? Эти параметры мы будем получать в middleware и в ней будем решать есть ли доступ у данного пользователя к этому контроллеру. Что дает нам гарантию что обычный пользователь не получит доступ к функциям админа, а амин не получит доступ к функциям создателя и тд. Так же это удобно тем что открыв контроллер мы сразу будем видеть все параметры доступа и конфигурации. Написать за вас промежуточное ПО я к сожалению или к радости не смогу =) Тут нужно иметь четкое представление о доступах в вашем сервисе, но минимальный пример доступа к контроллерам только админам покажу:
module.exports = {
async execute(fastify, command, request, reply) => {
try {
// Получение id из объекта sign который
// был инициализирован после проверки подписи
let id = request?.sign.vk_user_id;
//
let _auth = command?.auth; // true
let _root = command?.root; // true
if (id == _auth) {
// Получение данных о пользователе с бд или любого хранилища ...
let user = { name: "Artur Frank", root: 1 };
//
if (!_root || user.role == _root) { request.body = { ...{ id: id }, ...request.body }; }
else { return fastify.response.All(403, { message: `403 Forbidden` }, reply); }
}
else {return fastify.response.All(400, { message: `400 Bad Request` }, reply);}
}
catch (error) {
log.error(error);
return fastify.response.All(500, { message: `500 Internal Server Error` }, reply);
}
}
}
Если разобраться то тут все просто command?.root
это у нас те самые параметры в контроллерах о которых говорили выше. Если root: true
то middleware проверит является ли пользователь root и если да то внесет его id(можно передать любые нужные данные) в body и передаст всю информацию в наш контроллер.
Но если проверка прошла не успешно то middleware отправил ответ клиенту. В нашем случае я указал код ответа 403 в тех случаях если контроллер запрашивает пользователь у которого нет прав. И код 400 если пользователь вообще не прощел проверку подписи параметров запуска и нам не известно кто реально этот юзер.
В любом случае если мы передаем запрос клиенту через return fastify.response обработка кода обрывается и контроллер запущен не будет. Но если мы вместо ответа пользователю постараемся вернуть некие данные то контроллер будет запущен. Так же стоит учесть что middleware едина для всех контроллеров но в ней можно продумать вариативную систему проверки опираясь на предоставляемые данные от контроллеров и пользователя.
Last updated
Was this helpful?