www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Как создать RESTful API Node.js с JWT, Auth и PostgreSQL

Дата публикации Oct 3, 2019

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

Многоуровневая архитектура обеспечивает повышенную гибкость, удобство обслуживания и масштабируемость, а также упрощает написание, тестирование и обслуживание. Звучит хорошо, но как вы можете реализовать это с использованием современных технологий?

Для тех из вас, кто является новичком в Node.js и RESTful API, мы написали практическое руководство, которое поможет вам создать RESTful API, который можно превратить в крупный сервис. В этом руководстве мы покажем вам, как начать создавать RESTful API в три этапа. Метод JSON Web Token поможет нам обрабатывать аутентификацию, а PostgreSQL будет нашей базой данных.

Итак, наши шаги по написанию RESTful API:

> Инициализация проекта Node.js
> JWT аутентификация
> Добавление слоев

Инициализация проекта Node.js

Давайте начнем создавать наше приложение. Создайте пустую папку и инициализируйте новый проект с помощью следующей команды: npm init

Чтобы установить необходимые пакеты, запустите команду: npm i bcrypt bluebird body-parser express http jsonwebtoken lodash pg sequelize sequelize-values ​​- сохранить

Затем создайте следующие файлы в главной папке:

> config.js (настройки приложения, такие как соединения с базой данных, соли паролей и т. д.)
> db.js (отвечает за соединение с базой данных)
> router.js (обрабатывает http-запросы и отправляет их на контроллеры)
> index.js - (файл запуска)

Вот код, который содержат наши файлы:

config.js:

module.exports = {
порт: 3000,
dbConnectionString: «ваше соединение с postgresql»,
saltRounds: 2,
jwtSecret: «Тайна»,
tokenExpireTime: «6 ч»
}

db.js:

const config = require (‘./ config’);
const Sequelize = require («sequelize»);
var sequelize = new Sequelize (config.dbConnectionString);
требовать ( «sequelize-ценности») (sequelize);

module.exports = sequelize;

router.js:

module.exports.set = app => {
// конечные точки будут здесь в ближайшее время
}

index.js:

const express = require («экспресс»);
const http = require (‘http’);
const bodyParser = require («body-parser»);
const app = express ();
const config = require (‘./ config’);
const router = require (‘./ router’);

app.use (bodyParser.json ());
app.use (bodyParser.urlencoded ({
расширенный: правда
}));
app.use (express.static ( «клиент»));
router.set (приложение);

app.listen (config.port, () => console.log (listening Приложение прослушивает порт ‘+ config.port));

После того как вы закончили создавать файлы в главной папке, вам нужно определить модели данных. Для этого создайте папку моделей с файлом index.js внутри. Так:

/models/index.js:

const Sequelize = require («sequelize»);
const sequelize = require (‘../ db’);

const User = sequelize.define ("пользователь", {
Логин: Sequelize.STRING,
пароль: Sequelize.STRING,
});

const Order = sequelize.define (‘order’, {
название: Sequelize.STRING,
свидание: {
Тип: Sequelize.DATE,
defaultValue: Sequelize.NOW
},
Идентификатор пользователя: {
Тип: Sequelize.INTEGER,
Ссылки: {
модель: пользователь,
ключ: "id"
}
}
});

User.hasMany (Order, {foreignKey: ‘user_id’});

module.exports = {
Пользователь,
порядок
}

Так вы начинаете свой многослойный проект Node.js. На данный момент у нас есть точка входа в наше приложение (index.js), две модели БД (models / index.js) и некоторая базовая конфигурация.

Аутентификация JWT

Прежде чем писать настоящий API, давайте добавим аутентификацию в наше приложение. Создайте папку служб с файлами user.js и auth.js внутри. Так:
/services/index.js

const sequelize = require (‘../ db’);
const Users = требуется (‘../ models’). User;

const addUser = user => Users.create (user);

const getUserByLogin = login => Users.findOne ({где: {login}});

module.exports = {
Добавить пользователя,
getUserByLogin
}

После входа пользователя в систему каждый последующий запрос будет включать токен (JWT), позволяющий пользователю получать доступ к маршрутам, услугам и ресурсам в соответствии с разрешениями, хранящимися в токене.

/services/auth.js будет обрабатывать аутентификацию JWT:

const bcrypt = require (‘bcrypt’);
const jwt = require («jsonwebtoken»);

const Users = требуется (‘../ models’). User;
const config = require (‘../ config’);

const authenticate = params => {
вернуть Users.findOne ({
где: {
Логин: params.login
},
сырье: правда
}). затем (пользователь => {
если (! пользователь)
выбросить новую ошибку («Проверка подлинности не удалась. Пользователь не найден.»);
if (! bcrypt.compareSync (params.password || ‘’, user.password))
выбросить новую ошибку («Ошибка аутентификации. Неверный пароль.»);
полезная нагрузка const = {
Логин: user.login,
id: user.id,
время: новая дата ()
};

var token = jwt.sign (payload, config.jwtSecret, {
expiresIn: config.tokenExpireTime
});
возвратный токен;
});
}

module.exports = {
Аутентифицировать
}

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

Давайте создадим файл auth.js и поместим его в папку контроллеров

/controllers/auth.js:

const config = require (‘../ config’);
const jwt = require («jsonwebtoken»);
const bcrypt = require (‘bcrypt’);

const authService = require (‘../ services / auth’);
const userService = require (‘../ services / user’);

функция входа в систему (req, res) {
вернуть authService.authenticate (req.body)
.then (token => {
res.send ({
успех: правда,
данные: {токен}
});
})
.catch (err => {
res.send ({
успех: ложь,
message: err.message // не лучшая обработка ошибок.
// для лучшей обработки ошибок посетите репозиторий github, ссылка приведена ниже
});
})
};

регистр функции (req, res) {
var login = req.body.login;
return userService.getUserByLogin (req.body.login || ‘’)
.then (существует => {

если (существует) {
вернуть res.send ({
успех: ложь,
сообщение: ‘Регистрация не удалась. Пользователь с этим адресом электронной почты уже зарегистрирован.
});
}

var user = {
Логин: req.body.login,
пароль: bcrypt.hashSync (req.body.password, config.saltRounds)
}

вернуть userService.addUser (пользователь)
.then (() => res.send ({success: true}));
});
};

module.exports = {
авторизоваться,
регистр
}

После этого нам нужно добавить конечные точки в наш API.

Вы можете сделать это в файле router.js:

const authController = require (‘./ controllers / auth’);

module.exports.set = app => {
app.post (login / login ’, authController.login);
app.post (‘/ register’, authController.register);
}

Давайте запустим сервер, запустив командный узел index.js и протестируем функциональность входа и регистрации.

Добавление слоев

Теперь у нас есть слой Controller и слой доступа к данным в нашем приложении. Чтобы связать их вместе, нам нужен сервисный слой между ними.

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

Уровень представления (пользователь) взаимодействует с уровнем контроллеров (API), который использует уровень службы (бизнес-правила) для доступа и изменения данных через уровень доступа к данным.

Итак, начнем с нашего первого сервиса для модели заказа.

Создайте файл services / order.js

const Orders = требовать (‘../ models’). Order;

const getAll = () => Orders.findAll ();

const getById = id => Orders.findById (id);

const add = order => Orders.create (заказ);

module.exports = {add, getAll, getById};

Теперь мы можем создать контроллер для работы с этим сервисом.

Контроллеры / order.js

const orderService = require (‘../ services / order’);

function getOrders (req, res) {
orderService.getAll ()
.then (data => res.send (data));
};

function getOrder (req, res) {
orderService.getById (req.params.id)
.then (data => res.send (data));
}

function addOrder (req, res) {
orderService.add ({
title: req.body.title,
user_id: 1
})
.then (data => res.send (data));
};

module.exports = {
getOrders,
GetOrder,
addOrder
}

И еще одна вещь, которую мы должны завершить в RESTful API, - добавить конечные точки в router.js:

const orderController = require (‘./ controllers / order’);
//…
app.get (orders / orders ’, orderController.getOrders);
app.get (orders / orders /: id ’, orderController.getOrder);
app.post (‘/ orders’, orderController.addOrder);

Вот несколько примеров тестирования работающего API:

Следующее, что нам нужно, это разрешить доступ только аутентифицированным пользователям. Для этого добавим промежуточное ПО, которое проверяет, вошел ли пользователь в систему:

/ auth.js промежуточное программное:

const jwt = require («jsonwebtoken»);
const config = require (‘../ config’);

const checkAuth = (req, res, next) => {
var token = req.headers [‘token’];
если (! токен)
return res.status (403) .send ({auth: false, сообщение: «Токен не предоставлен».

jwt.verify (токен, config.jwtSecret, (ошибочный, декодированный) => {
если (ошибаться)
return res.status (500) .send ({auth: false, сообщение: ‘Не удалось аутентифицировать токен.’});

req.user = {
Логин: decoded.login,
id: decoded.id
};

следующий();
});
}

module.exports = {
checkAuth
}

После этого промежуточное программное обеспечение для аутентификации следует использовать в качестве аргумента промежуточного программного обеспечения (второго) в функциях конечных точек. Теперь пользователь не может получить доступ к данным без предоставления действительного токена аутентификации.

app.get (orders / orders ’, authMiddleware.checkAuth, orderController.getOrders);
app.get (orders / orders /: id ’, authMiddleware.checkAuth, orderController.getOrder);
app.post (orders / orders ’, authMiddleware.checkAuth, orderController.addOrder);
app.get (user / user_orders ’, authMiddleware.checkAuth, userController.getUsersWithOrders)

Как видите, это работает :)
Последнее, что нам нужно сделать, это определить функцию addOrder.

function addOrder (req, res) {
orderService.add ({
title: req.body.title,
user_id: req.user.id
})
.then (data => res.send (data));
};

Вот и все! Мы создали небольшое приложение с RESTful API. В соответствии с концепцией многоуровневой архитектуры, у нас есть уровень контроллеров, уровень обслуживания и уровень доступа к данным. Наш API с авторизацией JWT позволяет легко добавить презентационный слой, например, веб-приложение или мобильное приложение.

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map