Промежуточное ПО

Хорошо, мы умеем писать контроллеры и частично можем запустить простенькую 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?