Узнайте, как объединить эти технологии с практической демонстрацией.

Управление доступом на основе ролей — это безопасный механизм аутентификации. Вы можете использовать его, чтобы ограничить доступ к определенным ресурсам для пользователей с определенными ролями.

Этот тип аутентификации помогает системным администраторам управлять разрешениями в соответствии с назначенными пользователями ролями. Этот уровень детального контроля добавляет уровень безопасности, позволяя приложениям предотвращать несанкционированный доступ.

Внедрение механизма управления доступом на основе ролей с использованием Passport.js и JWT

Управление доступом на основе ролей (RBAC) — это популярный механизм, используемый для принудительного применения ограничений доступа в приложениях на основе ролей и разрешений пользователей. Существуют различные методы реализации механизма RBAC.

Два популярных подхода включают использование специализированных библиотек RBAC, таких как ДоступКонтроль или использование существующих библиотек аутентификации для реализации механизма.

instagram viewer

В этом случае веб-токены JSON (JWT) обеспечивают безопасный способ передачи учетных данных для аутентификации, в то время как Passport.js упрощает процесс аутентификации, обеспечивая гибкую аутентификацию промежуточное ПО.

Используя этот подход, вы можете назначать роли пользователям и кодировать их в JWT при их аутентификации. Затем вы можете использовать JWT для проверки личности пользователя и ролей в последующих запросах, обеспечивая авторизацию на основе ролей и контроль доступа.

Оба подхода имеют свои преимущества и могут быть эффективными при реализации RBAC. Выбор между тем, какой метод реализовать, будет зависеть от конкретных требований вашего проекта.

Вы можете скачать код этого проекта с его Репозиторий GitHub.

Настройка проекта Express.js

Для начала, настроить проект Express.js локально. После того, как вы настроите проект, продолжайте и установите эти пакеты:

npm установить cors dotenv mongoose cookie-parser jsonwebtoken mongodb \
паспорт паспорт-местный

Следующий, создать базу данных MongoDB или настроить кластер на MongoDB Atlas. Скопируйте URI подключения к базе данных и добавьте его в .env файл в корневом каталоге вашего проекта:

CONNECTION_URI="URI-адрес подключения"

Настройка подключения к базе данных

В корневом каталоге создайте новый утилиты/db.js файл и добавьте приведенный ниже код, чтобы установить соединение с кластером MongoDB, работающим в Atlas, с помощью Mongoose.

константа мангуст = требовать('мангуста');

константа подключить БД = асинхронный () => {
пытаться {
Ждите mongoose.connect (процесс.env. CONNECTION_URI);
консоль.бревно("Подключено к MongoDB!");
} ловить (ошибка) {
консоль.ошибка(«Ошибка подключения к MongoDB:», ошибка);
}
};

модуль.экспорт = подключить БД;

Определите модель данных

В корневом каталоге создайте новый модель/user.model.js файл и добавьте следующий код, чтобы определить модель данных для данных пользователей с помощью Mongoose.

константа мангуст = требовать('мангуста');

константа пользовательская схема = новый мангуста. Схема({
имя пользователя: Нить,
пароль: Нить,
роль: Нить
});

модуль.экспорт = мангуст.модель('Пользователь', пользовательская схема);

Создайте контроллер для конечных точек API.

Создать новый контроллеры/user.controller.js файл в корневом каталоге и добавьте приведенный ниже код.

Сначала сделайте этот импорт:

константа Пользователь = требовать('../модели/user.model');
константа паспорт = требовать('заграничный пасспорт');
константа { сгенерировать токен } = требовать('../промежуточное ПО/аутентификация');
требовать('../промежуточное ПО/паспорт')(заграничный пасспорт);

Затем определите логику для управления регистрацией пользователей и входом в систему:

экспорт.registerUser = асинхронный (требование, разрешение) => {
константа {имя пользователя, пароль, роль} = req.body;

пытаться {
Ждите User.create({имя пользователя, пароль, роль});
рез.статус(201).json({ сообщение: «Пользователь успешно зарегистрирован» });
} ловить (ошибка) {
консоль.лог (ошибка);
рез.статус(500).json({ сообщение: 'Произошла ошибка!' });
}
};

экспорт.loginUser = (запрос, разрешение, следующий) => {
паспорт.аутентифицировать('местный', { сеанс: ЛОЖЬ }, (ошибка, пользователь, информация) => {
если (ошибка) {
консоль.log (ошибка);

возвращаться рез.статус(500).json({
сообщение: «Произошла ошибка при входе в систему»
});
}

если (!пользователь) {
возвращаться рез.статус(401).json({
сообщение: 'Неверные логин или пароль'
});
}

req.login (пользователь, { сеанс: ЛОЖЬ }, (ошибка) => {
если (ошибка) {
консоль.log (ошибка);

возвращаться рез.статус(500).json({
сообщение: «Произошла ошибка при входе в систему»
});
}

константа {_id, имя пользователя, роль} = пользователь;
константа полезная нагрузка = { ID пользователя: _id, имя пользователя, роль };
константа токен = generateToken (полезная нагрузка);
res.cookie(жетон, токен, { httpТолько: истинный });
возвращаться рез.статус(200).json({ сообщение: 'Авторизация успешна' });
});
})(запрос, разрешение, следующий);
};

регистрацияПользователь Функция обрабатывает регистрацию нового пользователя, извлекая имя пользователя, пароль и роль из тела запроса. Затем он создает новую запись пользователя в базе данных и отвечает сообщением об успешном завершении или ошибкой, если таковая возникает во время процесса.

С другой стороны, логинПользователь Функция упрощает вход пользователя в систему, используя стратегию локальной аутентификации, предоставляемую Passport.js. Он аутентифицирует учетные данные пользователя и возвращает токен после успешного входа в систему, который затем сохраняется в файле cookie для последующих аутентифицированных запросов. Если в процессе входа в систему возникнут какие-либо ошибки, он вернет соответствующее сообщение.

Наконец, добавьте код, реализующий логику извлечения данных всех пользователей из базы данных. Мы будем использовать эту конечную точку в качестве ограниченного маршрута, чтобы гарантировать, что только авторизованные пользователи с ролью администратор может получить доступ к этой конечной точке.

экспорт.getUsers = асинхронный (требование, разрешение) => {
пытаться {
константа пользователи = Ждите Пользователь. найти ({});
res.json (пользователи);
} ловить (ошибка) {
консоль.лог (ошибка);
рез.статус(500).json({ сообщение: 'Произошла ошибка!' });
}
};

Настройка стратегии локальной аутентификации Passport.js

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

Создать новый промежуточное ПО/passport.js файл в корневом каталоге и добавьте следующий код.

константа Локальная стратегия = требовать('местный паспорт').Стратегия;
константа Пользователь = требовать('../модели/user.model');

модуль.экспорт = (заграничный пасспорт) => {
паспорт.использовать(
новый Локальная стратегия(асинхронный (имя пользователя, пароль, готово) => {
пытаться {
константа пользователь = Ждите User.findOne({имя пользователя});

если (!пользователь) {
возвращаться сделанный(нулевой, ЛОЖЬ);
}

если (user.password !== пароль) {
возвращаться сделанный(нулевой, ЛОЖЬ);
}

возвращаться сделанный(нулевой, пользователь);
} ловить (ошибка) {
возвращаться сделано (ошибка);
}
})
);
};

Этот код определяет локальную стратегию password.js для аутентификации пользователей на основе предоставленных ими имени пользователя и пароля.

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

Создайте промежуточное ПО для проверки JWT

Внутри промежуточное ПО каталог, создайте новый файл auth.js и добавьте следующий код, чтобы определить промежуточное программное обеспечение, которое создает и проверяет JWT.

константа джвт = требовать('jsonwebtoken');
константа секретный ключ = процесс.env. СЕКРЕТНЫЙ КЛЮЧ;

константа Генерировать Токен = (полезная нагрузка) => {
константа токен = jwt.sign (полезная нагрузка, секретный ключ, { истекает: '1ч' });
возвращаться жетон;
};

константа подтвердитьТокен = (требуемая роль) =>(запрос, разрешение, следующий) => {
константа токен = req.cookies.token;

если (! токен) {
возвращаться рез.статус(401).json({ сообщение: «Токен не предоставлен» });
}

jwt.verify (токен, секретный ключ, (ошибка, декодировано) => {
если (ошибка) {
возвращаться рез.статус(401).json({ сообщение: «Недействительный токен» });
}

req.userId = декодированный.userId;

если (decoded.role !== requiredRole) {
возвращаться рез.статус(403).json({
сообщение: «У вас нет полномочий и разрешений для доступа к этому ресурсу».
});
}

следующий();
});
};

модуль.exports = { generateToken, verifyToken };

сгенерировать токен функция создает JWT с указанным временем истечения срока действия, в то время как VerifyToken функция проверяет наличие и действительность токена. Кроме того, он также проверяет, содержит ли декодированный токен требуемую роль, по сути, гарантируя, что доступ имеют только пользователи с авторизованной ролью и разрешениями.

Чтобы уникально подписать JWT, вам необходимо сгенерировать уникальный секретный ключ и добавить его в свой .env файл, как показано ниже.

SECRET_KEY="Это образец секретного ключа."

Определите маршруты API

В корневом каталоге создайте новую папку и назовите ее route. Внутри этой папки создайте новый userRoutes.jsи добавьте следующий код.

константа экспресс = требовать('выражать');
константа роутер = экспресс. Маршрутизатор();
константа пользовательские контроллеры = требовать('../контроллеры/пользовательконтроллер');
константа {проверитьтокен} = требовать('../промежуточное ПО/аутентификация');

роутер.пост('/апи/регистр', userControllers.registerUser);
роутер.пост('/апи/логин', userControllers.loginUser);

роутер.получить('/API/пользователи', проверитьТокен('админ'), userControllers.getUsers);

модуль.экспорт = маршрутизатор;

Этот код определяет маршруты HTTP для REST API. пользователи маршрут, в частности, серверы в качестве защищенного маршрута. Ограничив доступ пользователям с администратор роль, вы эффективно применяете управление доступом на основе ролей.

Обновите файл основного сервера

Откройте свой сервер.js файл и обновите его следующим образом:

константа экспресс = требовать('выражать');
константа кор = требовать(корс);
константа cookieParser = требовать('cookie-парсер');
константа приложение = экспресс();
константа порт = 5000;
требовать('дотенв').конфиг();
константа подключить БД = требовать('./утилиты/дб');
константа паспорт = требовать('заграничный пасспорт');
требовать('./промежуточное ПО/паспорт')(заграничный пасспорт);

подключить БД();

app.use(express.json());
app.use (express.urlencoded({ расширенный: истинный }));
app.use(cors());
app.use(cookieParser());
app.use(passport.initialize());

константа пользовательские маршруты = требовать('./маршруты/userRoutes');
приложение.использовать('/', пользовательские маршруты);

app.listen (порт, () => {
консоль.бревно(`Сервер работает на порту ${порт}`);
});

Наконец, запустите сервер разработки, чтобы запустить приложение.

узел server.js

Используйте механизм RBAC для повышения эффективности ваших систем аутентификации

Внедрение управления доступом на основе ролей — эффективный способ повысить безопасность ваших приложений.

Хотя включение существующих библиотек аутентификации для создания эффективной системы RBAC является отличным подходом, использование библиотек RBAC для явно определять роли пользователей и назначать разрешения обеспечивает еще более надежное решение, в конечном итоге повышая общую безопасность вашего приложение.