Наш 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.