Запуск REST API с помощью Node.JS #3

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

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

Что такое JWT? (JSON Web Tokens)

JWT — это закодированная строка, которая будет использоваться в качестве ключа для выполнения запроса к нашему API.

При каждом запросе к нашему API токен будет проверяться, что позволит успешно завершить транзакцию или нет.

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

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

Подробнее о компании JWT читайте здесь.

Реализация аутентификации JWT

Поскольку у наших пользователей нет пароля в банке, давайте начнем с этого и добавим пароль для них.
Для простоты, вот зашифрованный пароль 123456: 16fd10090c85fadf1e2413980214b135fafa0169ded1939004ecc4e17dc31b77.
Давайте обновим наших пользователей и добавим поле пароля.

Не забудьте обновить модель пользователя с этим новым полем!

Мы также изменим метод создания пользователя, чтобы он создавался с зашифрованным паролем:

const crypto = require('crypto');
const secret = 'minhastringdeseguranca101010';

exports.post = async (req, res, next) => {
   const hash = crypto.createHmac('sha256', secret)
       .update(req.body.senha)
       .digest('hex');
   const usuario = await UsuarioModel.create({
       ...req.body,
       senha: hash
   });
   res.status(200).send(usuario);
};
Войдите в полноэкранный режим Выход из полноэкранного режима
npm install jsonwebtoken
Войдите в полноэкранный режим Выход из полноэкранного режима

Мы создадим папку в src под названием Middleware, а внутри нее файл Auth.js

const jwt = require('jsonwebtoken');
const secret = 'minhastringdeseguranca101010';

exports.auth = (req, res, next) => {
 const token = req.headers['authorization'];
 if (!token) return res.status(401).send({ auth: false, message: 'Essa rota requer autenticação.' });
  jwt.verify(token, secret, function(err, decoded) {
   if (err) return res.status(500).send({ auth: false, message: 'Token não autorizado.' });

   req.currentUser = decoded.userId;
   next();
 });
}
Войдите в полноэкранный режим Выход из полноэкранного режима

В этом методе мы возьмем значение авторизации из заголовка и проверим его с помощью библиотеки JWT.

Мы также создаем контроллер для выполнения входа в систему, AuthController.js

Обратите внимание, что мы используем библиотеку под названием crypto, она поставляется в комплекте с узлом, установка не требуется.

const UsuarioModel = require('../Models/Usuario');
const crypto = require('crypto');
const jwt = require('jsonwebtoken');
const secret = 'minhastringdeseguranca101010';

exports.login = async (req, res, next) => {
   const { senha, nome } = req.body;
   const hash = crypto.createHmac('sha256', secret)
       .update(senha)
       .digest('hex');

   const usuario = await UsuarioModel.findOne({ nome, senha: hash });
   if (usuario) {
       const token = jwt.sign({ userId: usuario._id }, secret);
       res.send({auth: true, token})
   } else {
       res.status(401).send({ auth: false, error: 'Nome ou senha inválidos.' })
   }
};
Войдите в полноэкранный режим Выход из полноэкранного режима

Мы добавили маршрут входа в систему: AuthRoute.js

const AuthController = require('../Controllers/AuthController');

module.exports = (app) => {
   app.post('/login', AuthController.login);
}
Войдите в полноэкранный режим Выход из полноэкранного режима

И вставьте его в Routes/index.js

const UsuarioRoute = require('./UsuarioRoute');
const AuthRoute = require('./AuthRoute');

module.exports = (app) => {
   UsuarioRoute(app);
   AuthRoute(app);
}
Войдите в полноэкранный режим Выход из полноэкранного режима

Нам нужно изменить наш файл маршрутов пользователя, чтобы добавить промежуточное ПО, которое мы создали выше:

const UsuarioController = require('../Controllers/UsuarioController');
const auth = require('../Middleware/Auth').auth;

module.exports = (app) => {
   app.post('/usuario', auth, UsuarioController.post);
   app.put('/usuario/:id', auth, UsuarioController.put);
   app.delete('/usuario/:id', auth, UsuarioController.delete);
   app.get('/usuarios', auth, UsuarioController.get);
   app.get('/usuario/:id', auth, UsuarioController.getById);
}
Войдите в полноэкранный режим Выход из полноэкранного режима

Вот так! Довольно просто, да? Давайте проверим!

Если мы попытаемся получить доступ к нашему маршруту get /users, то получим следующее сообщение:

Очень хорошо! Теперь давайте войдем в систему: У нас есть пользователь "Mariana" и пароль "123456".

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

Вернемся к запросу о пользователях, добавим параметр в заголовок: Authorization, со значением токена, который мы получили при входе в систему.

Видите, что теперь он возвращает данные, завершая запрос.

Вот так мы успешно реализовали схему аутентификации в нашем API!

*Для большей безопасности идеальным вариантом является использование файла .env для сохранения значения нашей секретной переменной.

До следующего раза 🙂 Увидимся в следующей статье!


Этот контент является репостом с сайта EZ.devs.

Оцените статью
devanswers.ru
Добавить комментарий