Если вы начинающий разработчик, возможно, вы знаете, что существует несколько типов проверок. Как разработчик веб-сайта, если вы используете React.js или любые другие технологии внешнего интерфейса, вы должны проверять данные перед их отправкой на сервер для выполнения запроса API. Это нормально, поскольку вы ограничиваете пользователя отправкой данных только в той структуре, которую вы хотите. Но что, если кто-то сделает запрос API напрямую, не используя интерфейс вашего веб-сайта/приложения? Они отправляют данные, которые могут быть вредными для нашего бэкэнда, и это может привести к сбою нашего сервера, если что-то не будет обработано должным образом. Также возможно, что анонимный пользователь попытается получить доступ к API, к которым должен иметь доступ только администратор. В этом руководстве мы научимся добавлять авторизацию на наш сервер Node.js, чтобы обрабатывать только авторизованный запрос пользователя.

Авторизация

Авторизация — это функция указания прав/привилегий доступа к ресурсам, которая связана с общей информационной безопасностью и компьютерной безопасностью, и с контролем доступа в частности.

Начиная

Для начала мы создадим базовую структуру для нашего бэкенда на Node.js и Express.js. Если вы новичок или хотите следовать руководству, вам следует ознакомиться с моей статьей, в которой я объяснил структуру приложения node.js. ("связь")

Сначала клонируем проект с https://github.com/MuqtadirBillah/node-express-basic-structure. Он содержит базовую структуру, которой мы будем следовать в этом уроке.

После того, как вы клонируете это репо, структура проекта будет выглядеть так:

В этом проекте к нему добавлена ​​очень простая аутентификация. Мы его сначала улучшим потом, добавим новые маршруты и добавим к ним авторизацию.

Добавить аутентификацию

Мы добавим в наш проект два новых пакета: «bcryptjs» и «jsonwebtoken». Чтобы установить эти пакеты, вам нужно выполнить следующую команду.

npm install bcryptjs jsonwebtoken

Теперь перед запуском вам нужно запустить локальный сервер mongodb. Затем просто выполните приведенную ниже команду на терминале, чтобы запустить наш сервер.

npm start

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

Я буду менять только поле пароля в функции регистрации. Я буду использовать bcrypt для хеширования и сохранения в базе данных.

Чтобы использовать bcryptjs, нам нужно сначала импортировать его вверху.

const bcrypt = require('bcryptjs');

Далее нам нужно его хешировать. Я буду хэшировать с автосолью. Вы можете прочитать документы на bcryptjs.

let hashedPassword = bcrypt.hashSync(req.body.password, 10);

А затем я заменю req.body.password на hashedPassword, чтобы в нашу базу данных добавлялся только хешированный пароль.

const user = await new User({
    email: req.body.email,
    password: hashedPassword,
    username: req.body.username,
    creation_date: moment().format("MMMM Do YYYY, h:mm:ss a")
})

Теперь, когда логика регистрации немного улучшена, давайте поработаем над логикой входа в систему.

Теперь в логической функции мы будем сравнивать хешированный пароль с паролем, введенным функцией bcrypt.

if(bcrypt.compareSync(req.body.password, docs[0].password)){
    res.status(200).json({ status: "success" })
}
else{
    res.send("Invalid Credentials!");
}

Теперь, когда пароль подобран, мы создадим jwt (веб-токен json) с основными данными, которые будут использоваться и проверяться при выполнении запроса API. (Вы можете добавить в него больше деталей, но в настоящее время я сохраняю в нем только имя пользователя и адрес электронной почты).

Теперь здесь я буду подписывать jwt и отправлять токен с ответом API. Вы можете прочитать официальную документацию на JWT. Обязательно импортируйте его вверху.

if(bcrypt.compareSync(req.body.password, docs[0].password)){
    let token = jwt.sign({ foo: 'bar' }, "f0af17449a83681de22db7ce16672f16f37131bec0022371d4ace5d1854301e0");
    res.status(200).json({ status: "success", token: token })                    
}
else{
    res.send("Invalid Credentials!");
}

Теперь давайте проверим, все ли работает так, как ожидалось. Чтобы проверить это, мы будем использовать postman.

Тестирование API регистрации

Если вы получаете ответ с сообщением «добавлено!», это означает, что ваш пользователь регистрируется. Чтобы подтвердить это, вы можете просмотреть его в своей базе данных. В настоящее время я использую для этого Mongodb Compase.

Здесь я вижу информацию о зарегистрированном пользователе.

Далее я буду тестировать API входа. Мы проделаем это и в Postman, изменив url.

Теперь, если вы войдете в систему с правильными учетными данными, вы получите статус и jwt.

Давайте скопируем jwt, поскольку мы будем использовать его позже.

Создание авторизованного пользовательского маршрута

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

Теперь мы создадим маршрут, который будет доступен только зарегистрированному пользователю. Для этого мы сначала добавим новый контроллер.

Я создам контроллер с именем «userController» и функцию getJoke(), которая будет получать шутки от стороннего API. В конце я экспортирую эту функцию, чтобы мы могли получить доступ к нашему файлу маршрутизатора.

Теперь я создам userRoutes в папке маршрутов.

const express = require("express");
const userController = require("../controllers/userController")
const userRouter = express.Router();

userRouter.route("/joke").get(userController.getJoke);

module.exports = userRouter;

Затем я импортирую его в index.js в папку маршрутов.

const { Router: expressRouter } = require("express");
const router = expressRouter();

// auth routes
const authRouter = require("./authRoutes");
router.use("/auth", authRouter);

// user routes 
const userRouter = require("./userRoutes");
router.use("/user", userRouter);

module.exports = router;

Теперь давайте протестируем API.

Вот и получаем ответ.

Добавление авторизации

Теперь я хочу, чтобы только пользователь с правильным jwt мог получить доступ к этому API. Для этого я создам промежуточное программное обеспечение под названием verify.js в новой папке под названием «промежуточное программное обеспечение».

const jwt = require("jsonwebtoken")
const { jwt_key } = require("../config/db.config")
const { handleResponseWithStatus } = require("../helper/utils");



const verifyToken = (req, res, next)=>{
    const token = req.headers.token
    if(token!=undefined){
        jwt.verify(token, jwt_key, function(err, decoded) {
            if(err){
                console.log(err)
                res.send({ status: "error", error: 'Unauthorized User!' });
            }
            else{
                if(decoded!=undefined){
                    console.log(decoded)
                    next();
                }
                else{
                    res.send({ status: "error", error: 'Unauthorized User!' });
                }
            }
        });
    }
    else{
        res.send({ status: "error", error: 'Unauthorized User!' });
    }
}

module.exports = verifyToken;

Посмотреть этот файл можно по ссылке. Я импортирую эту функцию в index.js промежуточного ПО как isAuthenticated.

module.exports = {
    isAuthenticated: require("./verify"),
}

Затем я добавлю его в качестве промежуточного программного обеспечения в маршруты перед доступом к функции API, то есть к getJoke. Он будет добавлен в userRoutes.js

const express = require("express");
const userController = require("../controllers/userController")
const userRouter = express.Router();
const { isAuthenticated } = require("../middlewares");

userRouter.route("/joke").get(isAuthenticated, userController.getJoke);

module.exports = userRouter;

Теперь мы проверим, можем ли мы получить доступ к API «http://localhost:5000/api/user/joke» без каких-либо разрешений.

В настоящее время, если я попытаюсь получить к нему доступ. Выдает ошибку "Неавторизованный пользователь".

Теперь, чтобы заставить его работать, нам нужно проверить себя. Для этого мы будем отправлять JWT в заголовке, чтобы наше промежуточное ПО могло проверить, авторизован ли доступ пользователя.

Я добавляю имя ключа «токен» в раздел заголовка нашего почтальона и помещаю значение, которое мы получали при входе в систему как JWT.

Теперь, если мы попытаемся сделать запрос с токеном JWT в API getJoke, мы сможем получить к нему доступ.

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

GitHub Repo для этой статьи: https://github.com/MuqtadirBillah/node-express-basic-structure.git

Теперь вы знаете, как добавить авторизацию в API Node.js и Express.js.

Подпишитесь на меня, чтобы узнать больше интересных советов и подсказок на Musab Abbasi — Medium
Вы также можете найти меня на LinkedIn и Github