Узнайте, как объединить эти технологии с практической демонстрацией.
Управление доступом на основе ролей — это безопасный механизм аутентификации. Вы можете использовать его, чтобы ограничить доступ к определенным ресурсам для пользователей с определенными ролями.
Этот тип аутентификации помогает системным администраторам управлять разрешениями в соответствии с назначенными пользователями ролями. Этот уровень детального контроля добавляет уровень безопасности, позволяя приложениям предотвращать несанкционированный доступ.
Внедрение механизма управления доступом на основе ролей с использованием Passport.js и JWT
Управление доступом на основе ролей (RBAC) — это популярный механизм, используемый для принудительного применения ограничений доступа в приложениях на основе ролей и разрешений пользователей. Существуют различные методы реализации механизма RBAC.
Два популярных подхода включают использование специализированных библиотек RBAC, таких как ДоступКонтроль или использование существующих библиотек аутентификации для реализации механизма.
В этом случае веб-токены 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 для явно определять роли пользователей и назначать разрешения обеспечивает еще более надежное решение, в конечном итоге повышая общую безопасность вашего приложение.