Пропишемо сам роут для реєстрації та залогінення: routes/authRoutes.js
routes/authRoutes.js
const { Router } = require("express");
// контроллери і мідлвари
const authController = require("../controllers/authController");
const authMiddlewares = require("../middlewares/authMiddlewares");
// можна одразу деструктуризувати
// const { checkSignupUserData } = require("../middlewares/authMiddlewares");
const router = Router();
// signup - register new user
router.post(
"/signup",
authMiddlewares.checkSignupUserData,
authController.signup
);
// login - login user - authentification
router.post("/login", authController.login);
module.exports = router;
По суті ми прописали нові роути. signup - реєструє користувача (це для самого користувача з обмеженим функціоналом (без надання права встановлення ролі)), а login - автентифікує користувача.
Middleware checkSignupUserData у файлі middlewares/authMiddlewares.js - перевірятиме вхідні дані при реєстрації користувача, наявність користувача з таким email, якщо все ок, то пропускає далі
middlewares/authMiddlewares.js
const { catchAsync, AppError, userValidator } = require("../utils");
const User = require("../models/userModel");
exports.checkSignupUserData = catchAsync(async (req, res, next) => {
const { error, value } = userValidator.signupUserDataValidator(req.body);
if (error) {
console.log(error);
throw new AppError(400, "Invalid user data..");
}
const userExists = await User.exists({ email: value.email });
if (userExists) throw new AppError(409, "User with this email exists..");
req.body = value;
next();
});
У коді вище signupUserDataValidator - це валідація даних за допомогою Joi у файлі utils/userValidator.js. Тут всі поля на відповідність вимогам. Але при цьому role юзера не перевіряємо, бо вона буде створюватися автоматично.
Тут ми використовуємо змінні JWT_SECRET і JWT_EXPIRES_IN, які ми зберігаємо у файлі .env і завантажуємо в оточення піл час запуску сервера. (одразу вписати копію в .example файл, але з пустими даними)
enviroments/development.env
JWT_SECRET = "jfdsnfvlkndlk"
JWT_EXPIRES_IN='10m'
ВСЕ ВКАЗАНЕ ВИЩЕ ІТАК ПРАЦЮЄ, АЛЕ МОДНА ПРОВЕСТИ ДЕЯКИЙ РЕФАКТОРИНГ
Тут краще signToken винести в окремий файл і не тримати його в контролерах, а такод виносити в окремий файл все що повʼязано щ моделлю в даному випалку User
створимо папку services і в ньому файл jwtService.js і в неї винесемо функцію
НА ЦЬОМУ ЕТАПІ УЖЕ Є АВТОРИЗАЦІЯ. тобто роути сайнап і логін відкриті для всіх.
Але треба провести автентифікацію, щоб звертатися по ендпойнтах для зміни в БД могли тільки авторизовані користувачі. для цього потрібно прописати мідлварку захисту тобто, щоб доступ до внесення змін в бд був тільки з токеном
Щоб в програмі Postman передавати токен потрібно вибрати autorization і bearer token
тобто в роутах буде проходити протект, а потім інші роути
На цьому етапі уже працює -------
Додамо ще один роут для авторизованиз користувачів
routes/userRoutes.js
router.get("/get-me", getMe);
в контролерах напишемо юзер контролер якщо хочемо повертати залогіненого юзера по його jwt
controllers/userController.js
/**
* Get logged in user data.
*/
exports.getMe = (req, res) => {
res.status(200).json({
user: req.user,
});
};
-----------
напишемо мідлваоку доступу по ролях (якщо у вкащаному масиві є роль яка збігається із роллю нашого користувача, то пропустить, якшо немає, то поверне далі еррорку)
middlewares/authMiddlewares.js
// /**
// * Roles guard middleware
// * allowFor('admin', 'moderator')
// * use ONLY after 'protect'
// * @param {String} roles
// * @returns {Function}
// */
exports.allowFor =
(...roles) =>
(req, res, next) => {
if (roles.includes(req.user.role)) return next();
next(new AppError(403, "You are not allowed to perform this action.."));
};
після цього деякі роути можна закрити тільки для адміна і модератора.