Перед вами — первый материал из серии, посвящённой разработке полноценного веб-приложения, которое называется Budget Manager. Основные программные средства, которые будут использованы в ходе работы над ним — это Node.js для сервера, Vue.js для фронтенда, и MongoDB в роли базы данных.

Эти материалы рассчитаны на читателей, которые знакомы с JavaScript, имеют общее представление о Node.js, npm и MongoDB, и хотят изучить связку Node-Vue-MongoDB и сопутствующие технологии. Приложение будем писать с нуля, поэтому запаситесь любимым редактором кода. Для того, чтобы не усложнять проект, мы не будем пользоваться Vuex и постараемся сосредоточиться на самом главном, не отвлекаясь на второстепенные вещи.
Автор этого материала, разработчик из Бразилии, говорит, что ему далеко до JavaScript-гуру, но он, находясь в поиске новых знаний, готов поделиться с другими тем, что ему удалось найти.
Здесь мы рассмотрим следующие вопросы:
Код проекта, над которым мы будем работать, можно найти на GitHub.
Для начала создадим структуру папок для проекта, которая, в самом начале работы, должна выглядеть следующим образом:

Структура папок API
В ходе продвижения по материалу мы значительно расширим эту структуру.
Теперь нужно установить несколько зависимостей. Для этого перейдём в корневую папку проекта (здесь это
Рассмотрим некоторые из этих зависимостей и их роль в проекте:
После установки пакетов, если вы планируете использовать Git, создайте в корневой папке проекта файл
Теперь, когда предварительная подготовка завершена, займёмся программированием.
Создадим в папке
Этот файл содержит параметры подключения к базе данных и секретный ключ, который мы используем для создания JWT-токенов.
Здесь предполагается работа с локальным сервером MongoDB. При этом в строке
Создадим модель
Пакет
После этого, в тот же файл, добавим следующее:
Этот код предназначен для создания схемы данных
В сведения о клиенте будут входить адрес электронной почты (email), имя (name), телефон (phone), и финансовые документы (budgets). Финансовый документ включает такие данные, как его состояние (state), заголовок (title), элементы (items) и цена (price).
Продолжаем работать с файлом
В этой функции мы генерируем криптографическую соль и хэш для паролей пользователей.
Следом за кодом этой функции, добавим функцию, которая будет сравнивать пароли, проверяя правомерность доступа пользователя к системе:
Теперь, в конце файла, создадим модель
После того, как модель
Пакет
Теперь добавим в этот файл следующее:
Тут мы создаём экземпляр модели
В папке
Тут мы сначала переключили
После того, как мы справились с некоторыми из вспомогательных подсистем, займёмся настройкой сервера. Перейдите в папку
Мы начинаем с подключения
Для того чтобы запустить сервер, надо перейти в корневую директорию проекта и ввести команду
В директории
В строке

Благодаря такому подходу мы можем работать с
Далее, в файле
Как вариант, вместо использования пакета
Перейдём в корневую директорию проекта, откроем
Обратите внимание на то, что блок
Благодаря этим изменениям можно будет обращаться к корневой директории проекта с помощью псевдонима
После настройки псевдонимов перейдём в папку
Делаем мы это для того, чтобы обеспечить загрузку моделей до того, как в приложении будет загружено что-то другое.
Теперь начинаем создавать некоторые из методов API. Перейдём в папку
Обратите внимание на то, что, благодаря использованию модуля
Теперь, после подключения пакетов, сделаем в том же файле следующее:
Тут мы создаём пустой объект
Этот метод выполняет поиск объекта
Теперь нужен ещё один метод
Этот метод проверяет заголовки и получает заголовок
Займёмся созданием маршрутов API. Для этого перейдём в папку
В этот модуль мы передаём объект
Вернёмся теперь к файлу
Тут мы проверяем, прежде чем выполнять другие действия, загружено ли содержимое папки
Вернёмся в папку
Метод
Теперь, в том же файле, создадим метод, применяемый для тестовых целей, позволяющий вывести список всех пользователей, которые зарегистрировались в приложении, и нужный для проверки механизмов аутентификации:
Далее, создадим метод
Тут проверяется, при попытке регистрации нового пользователя, заполнены ли поля
На данном этапе работы над приложением будем считать, что методы API для работы с пользователями готовы.
Теперь создадим файл
Здесь мы импортируем библиотеку
Проверим то, что мы создали, предварительно запустив сервер приложения и сервер базы данных. А именно, если перейти по адресу http://localhost:3001/, то в окне терминала, где запущен сервер, можно будет увидеть сведения о запросе (там должно быть 200, что означает, что запрос прошёл успешно), и данные о времени ответа. Выглядеть это будет примерно так:

Приложение-клиент, то есть — браузер, должно вывести обычную страницу с текстом «Budget Manager API».
Проверим теперь маршрут
В окне сервера появится сообщение о запросе GET со статусом 404 (это говорит о том, что с сервером связаться удалось, но он не может предоставить то, что нам нужно) и о времени ответа.

Происходит это из-за того, что мы используем данную конечную точку API только для POST-запросов. Серверу нечего ответить, если мы выполняем GET-запрос.
Проверим маршруты
Всё это позволяет судить о том, что система аутентификации работает, однако, тут возникает вопрос о том, как проверить методы входа в систему, если у нас пока даже нет формы регистрации.
Один из способов решить эту проблему заключается в использовании программы Postman. Её можно либо загрузить и установить как обычное приложение, либо пользоваться ей формате расширения для браузера Chrome.
Для начала подключимся к конечной точке

В поле для адреса введём
Теперь попытаемся войти в систему с учётной записью администратора.

Для этого воспользуемся POST-запросом к конечной точке
Ответ сервера должен выглядеть так, как показано на рисунке ниже.

Далее, получим список пользователей системы.

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

Проверим теперь метод регистрации нового пользователя,

Для этого откроем новую вкладку, настроим POST-запрос к конечной точке

Теперь, если мы вернёмся к вкладке

На этом мы завершаем первую часть данной серии. Здесь вы узнали о том, как, с чистого листа, создать Node.js-приложение и настроить простую JWT-аутентификацию. В следующей части приступим к разработке пользовательского интерфейса приложения с использованием Vue.js.
Уважаемые читатели! Как по-вашему, подойдёт ли способ аутентификации пользователей, предложенный автором, для использования в продакшне?

Эти материалы рассчитаны на читателей, которые знакомы с JavaScript, имеют общее представление о Node.js, npm и MongoDB, и хотят изучить связку Node-Vue-MongoDB и сопутствующие технологии. Приложение будем писать с нуля, поэтому запаситесь любимым редактором кода. Для того, чтобы не усложнять проект, мы не будем пользоваться Vuex и постараемся сосредоточиться на самом главном, не отвлекаясь на второстепенные вещи.
Автор этого материала, разработчик из Бразилии, говорит, что ему далеко до JavaScript-гуру, но он, находясь в поиске новых знаний, готов поделиться с другими тем, что ему удалось найти.
Здесь мы рассмотрим следующие вопросы:
- Организация структуры проекта.
- Установка зависимостей и описание используемых библиотек.
- Работа с MongoDB и создание моделей Mongoose.
- Разработка методов API приложения.
- Подготовка маршрутов Express.
- Организация JWT-аутентификации с применением Passport.js.
- Тестирование проекта с использованием Postman.
Код проекта, над которым мы будем работать, можно найти на GitHub.
Структура проекта и установка зависимостей
Для начала создадим структуру папок для проекта, которая, в самом начале работы, должна выглядеть следующим образом:

Структура папок API
В ходе продвижения по материалу мы значительно расширим эту структуру.
Теперь нужно установить несколько зависимостей. Для этого перейдём в корневую папку проекта (здесь это
focus-budget-manager) и, предварительно сформировав package.json командой npm init, выполним следующую команду:npm i --save express body-parser mongoose consign cors bcrypt jsonwebtoken morgan passport passport-jwt module-aliasРассмотрим некоторые из этих зависимостей и их роль в проекте:
- Express. Это — фреймворк для Node.js, мы будем пользоваться им для того, чтобы облегчить разработку API.
- Body Parser. Этот пакет является средством разбора тела запросов для Node.js. Он помогает парсить тела входящих запросов до того, как они попадут в обработчики, в результате, работать с ними можно, используя свойство
req.body.
- Mongoose. Это — средство объектного моделирования для MongoDB, которое предназначено для работы в асинхронной среде.
- Consign. Этот пакет является вспомогательным средством, использовать его не обязательно. Он предназначен для организации автозагрузки скриптов.
- CORS. Этот пакет является вспомогательным средством для Connect/Express, которое можно использовать для активации CORS.
- Bcrypt. С помощью этого пакета мы будем генерировать криптографическую «соль» и хэши.
- Morgan. Это — вспомогательное средство для Node.js, предназначенное для логирования HTTP-запросов.
- Module Alias. Этот пакет позволяет создавать псевдонимы для папок и регистрировать собственные пути к модулям в Node.js.
После установки пакетов, если вы планируете использовать Git, создайте в корневой папке проекта файл
.gitignore. Запишите в него следующее:/node_modules/Теперь, когда предварительная подготовка завершена, займёмся программированием.
Файл BudgetManagerAPI/config/index.js
Создадим в папке
BudgetManagerAPI/config файл index.js и внесём в него следующий код:module.exports = {
secret: 'budgetsecret',
session: { session: false },
database: 'mongodb://127.0.0.1:27017/budgetmanager'
}Этот файл содержит параметры подключения к базе данных и секретный ключ, который мы используем для создания JWT-токенов.
Здесь предполагается работа с локальным сервером MongoDB. При этом в строке
127.0.0.1:27017 можно использовать localhost. Если хотите, можете работать с облачной базой данных MongoDB, созданной, например, средствами MLabs.Файл BudgetManagerAPI/app/models/user.js
Создадим модель
User, которая будет использоваться для JWT-аутентификации. Для этого надо перейти в папку BudgetManagerAPI/app и создать в ней директорию models, а в ней — файл user.js. В начале файла подключим зависимости:const mongoose = require('mongoose'),
bcrypt = require('bcrypt');Пакет
mongoose нужен здесь для того, чтобы создать модель User, средства пакета bcrypt будут использованы для хэширования паролей пользователей.После этого, в тот же файл, добавим следующее:
const Schema = mongoose.Schema({
username: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
},
clients: [{}]
});Этот код предназначен для создания схемы данных
User. Благодаря этому описанию за пользователем нашей системы будут закреплены следующие данные:- Имя пользователя (
username).
- Пароль (
password).
- Список клиентов (
clients).
В сведения о клиенте будут входить адрес электронной почты (email), имя (name), телефон (phone), и финансовые документы (budgets). Финансовый документ включает такие данные, как его состояние (state), заголовок (title), элементы (items) и цена (price).
Продолжаем работать с файлом
user.js, добавляем в него следующий код:// Здесь не будем пользоваться стрелочными функциями из-за автоматической привязки к лексической области видимости
Schema.pre('save', function (next) {
const user = this;
if (this.isModified('password') || this.isNew) {
bcrypt.genSalt(10, (error, salt) => {
if (error) return next(error);
bcrypt.hash(user.password, salt, (error, hash) => {
if (error) return next(error);
user.password = hash;
next();
});
});
} else {
return next();
}
});В этой функции мы генерируем криптографическую соль и хэш для паролей пользователей.
Следом за кодом этой функции, добавим функцию, которая будет сравнивать пароли, проверяя правомерность доступа пользователя к системе:
Schema.methods.comparePassword = function (password, callback) {
bcrypt.compare(password, this.password, (error, matches) => {
if (error) return callback(error);
callback(null, matches);
});
};Теперь, в конце файла, создадим модель
User:mongoose.model('User', Schema);Файл BudgetManagerAPI/config/passport.js
После того, как модель
User готова, создадим файл passport.js в папке BudgetManagerAPI/config. Начнём работу над этим файлом с подключения зависимостей:const PassportJWT = require('passport-jwt'),
ExtractJWT = PassportJWT.ExtractJwt,
Strategy = PassportJWT.Strategy,
config = require('./index.js'),
models = require('@BudgetManager/app/setup');Пакет
mongoose нужен для работы с моделью User, а passport-jwt — для организация аутентификации.Теперь добавим в этот файл следующее:
module.exports = (passport) => {
const User = models.User;
const parameters = {
secretOrKey: config.secret,
jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken()
};
passport.use(new Strategy(parameters, (payload, done) => {
User.findOne({ id: payload.id }, (error, user) => {
if (error) return done(error, false);
if (user) done(null, user);
else done(null, false);
});
}));
}Тут мы создаём экземпляр модели
User и находим пользователя, выполняя поиск по JWT-токену, полученному от клиента.Файл BudgetManagerAPI/config/database.js
В папке
BudgetManagerAPI/config создадим файл database.js, который ответственен за работу с базой данных. Добавим в этот файл следующее:module.exports = (mongoose, config) => {
const database = mongoose.connection;
mongoose.Promise = Promise;
mongoose.connect(config.database, {
useMongoClient: true,
promiseLibrary: global.Promise
});
database.on('error', error => console.log(`Connection to BudgetManager database failed: ${error}`));
database.on('connected', () => console.log('Connected to BudgetManager database'));
database.on('disconnected', () => console.log('Disconnected from BudgetManager database'));
process.on('SIGINT', () => {
database.close(() => {
console.log('BudgetManager terminated, connection closed');
process.exit(0);
})
});
};Тут мы сначала переключили
mongoose на использование стандартного объекта Promise. Если этого не сделать, можно столкнуться с предупреждениями, выводимыми в консоль. Затем мы создали стандартное подключение mongoose.Настройка сервера, файл services/index.js
После того, как мы справились с некоторыми из вспомогательных подсистем, займёмся настройкой сервера. Перейдите в папку
services и откройте уже имеющийся в ней файл index.js. Добавьте в него следующее:require('module-alias/register');
const http = require('http'),
BudgetManagerAPI = require('@BudgetManagerAPI'),
BudgetManagerServer = http.Server(BudgetManagerAPI),
BudgetManagerPORT = process.env.PORT || 3001,
LOCAL = '0.0.0.0';
BudgetManagerServer.listen(BudgetManagerPORT, LOCAL, () => console.log(`BudgetManagerAPI running on ${BudgetManagerPORT}`));Мы начинаем с подключения
module_alias, который мы настроим позже (шаг это необязателен, но такой подход поможет сделать код чище). Если вы решите не использовать пакет module_alias, то вместо @BudgetManagerAPI надо будет писать ./services/BudgetManagerAPI/config.Для того чтобы запустить сервер, надо перейти в корневую директорию проекта и ввести команду
node services в используемом вами интерпретаторе командной строки.Файл BudgetManagerAPI/config/app.js
В директории
BudgetManagerAPI/config создадим файл app.js. Для начала подключим зависимости:const express = require('express'),
app = express(),
bodyParser = require('body-parser'),
mongoose = require('mongoose'),
morgan = require('morgan'),
consign = require('consign'),
cors = require('cors'),
passport = require('passport'),
passportConfig = require('./passport')(passport),
jwt = require('jsonwebtoken'),
config = require('./index.js'),
database = require('./database')(mongoose, config);В строке
passportConfig = require('./passport')(passport) мы импортируем конфигурационный файл для passport, передавая passport в качестве аргумента, так как в passport.js имеется такая команда:
Благодаря такому подходу мы можем работать с
passport внутри файла passport.js без необходимости подключать его.Далее, в файле
app.js, начинаем работу с пакетами и устанавливаем секретный ключ:app.use(express.static('.'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(morgan('dev'));
app.use(cors());
app.use(passport.initialize());
app.set('budgetsecret', config.secret);Как вариант, вместо использования пакета
cors, можно сделать следующее:app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});Настройка package.json
Перейдём в корневую директорию проекта, откроем
package.json и добавим в него, сразу перед блоком dependencies, следующее:"homepage": "https://github.com/gdomaradzki/focus-gestor-orcamentos#readme",
"_moduleAliases": {
"@root": ".",
"@BudgetManager": "./services/BudgetManagerAPI",
"@BudgetManagerModels":"./services/BudgetManagerAPI/app/models",
"@BudgetManagerAPI":"./services/BudgetManagerAPI/config/app.js",
"@config": "./services/BudgetManagerAPI/config/index.js"
},
"dependencies": {Обратите внимание на то, что блок
dependencies уже имеется в файле, поэтому нужно добавить туда лишь блоки homepage и _moduleAliases.Благодаря этим изменениям можно будет обращаться к корневой директории проекта с помощью псевдонима
@root, к конфигурационному файлу index.js — используя псевдоним @config, и так далее.Файл BudgetManagerAPI/app/setup/index.js
После настройки псевдонимов перейдём в папку
BudgetManagerAPI/app и создадим новую папку setup, а в ней — файл index.js. Добавим в него следующее:const mongoose = require('mongoose'),
UserModel = require('@BudgetManagerModels/user');;
const models = {
User: mongoose.model('User')
}
module.exports = models;Делаем мы это для того, чтобы обеспечить загрузку моделей до того, как в приложении будет загружено что-то другое.
Файл BudgetManagerAPI/app/api/auth.js
Теперь начинаем создавать некоторые из методов API. Перейдём в папку
BudgetManagerAPI/app, создадим в ней директорию api, а в ней — файл auth.js. Запишем в него следующее:const mongoose = require('mongoose'),
jwt = require('jsonwebtoken'),
config = require('@config');Обратите внимание на то, что, благодаря использованию модуля
module_alias мы сделали код чище. Иначе пришлось бы писать примерно следующее:config = require('./../../config);Теперь, после подключения пакетов, сделаем в том же файле следующее:
const api = {};
api.login = (User) => (req, res) => {
User.findOne({ username: req.body.username }, (error, user) => {
if (error) throw error;
if (!user) res.status(401).send({ success: false, message: 'Authentication failed. User not found.' });
else {
user.comparePassword(req.body.password, (error, matches) => {
if (matches && !error) {
const token = jwt.sign({ user }, config.secret);
res.json({ success: true, message: 'Token granted', token });
} else {
res.status(401).send({ success: false, message: 'Authentication failed. Wrong password.' });
}
});
}
});
}Тут мы создаём пустой объект
api, в котором сохраним все необходимые методы. В метод login сначала передаём аргумент User, так как тут нужен метод для доступа к модели User, затем передаём аргументы req и res.Этот метод выполняет поиск объекта
User, который соответствует имени пользователя (username). Если имя пользователя распознать не удаётся, выдаём ошибку, в противном случае проверяем пароль и токен, привязанные к пользователю.Теперь нужен ещё один метод
api, который будет получать и парсить токен:api.verify = (headers) => {
if (headers && headers.authorization) {
const split = headers.authorization.split(' ');
if (split.length === 2) return split[1];
else return null;
} else return null;
}Этот метод проверяет заголовки и получает заголовок
Authorization. После всех этих действий мы, наконец, можем экспортировать объект api:module.exports = api;Маршруты API, файл BudgetManagerAPI/app/routes/auth.js
Займёмся созданием маршрутов API. Для этого перейдём в папку
services/BudgetManagerAPI/app и создадим в ней директорию routes, в которой создадим файл auth.js со следующим содержимым:const models = require('@BudgetManager/app/setup');
module.exports = (app) => {
const api = app.BudgetManagerAPI.app.api.auth;
app.route('/')
.get((req, res) => res.send('Budget Manager API'));
app.route('/api/v1/auth')
.post(api.login(models.User));
}В этот модуль мы передаём объект
app, благодаря чему можно установить маршруты. Здесь же мы задаём константу api, которую используем для работы с файлом auth.js в папке api. Тут мы задаём маршрут по умолчанию, '/', при обращении к которому пользователю передаётся строка «Budget Manager API». Тут же создаём маршрут '/api/v1/auth' (для работы с которым применяется POST-запрос). Для обслуживания этого маршрута используем метод login, передавая модель User как аргумент.Файл BudgetManagerAPI/config/app.js
Вернёмся теперь к файлу
app.js, который расположен в папке BudgetManagerAPI/config и добавим в него следующее (строка app.set('budgetsecret', config.secret) дана как ориентир, добавлять её в файл второй раз не надо):app.set('budgetsecret', config.secret);
consign({ cwd: 'services' })
.include('BudgetManagerAPI/app/setup')
.then('BudgetManagerAPI/app/api')
.then('BudgetManagerAPI/app/routes')
.into(app);
module.exports = app;Тут мы проверяем, прежде чем выполнять другие действия, загружено ли содержимое папки
setup, благодаря чему в первую очередь будет создан экземпляр модели. Затем загружаем методы API, и наконец — маршруты.Файл BudgetManagerAPI/app/api/user.js
Вернёмся в папку
BudgetManagerAPI/app/api и создадим в ней файл user.js. Поместим в него следующий код:const mongoose = require('mongoose');
const api = {};
api.setup = (User) => (req, res) => {
const admin = new User({
username: 'admin',
password: 'admin',
clients: []
});
admin.save(error => {
if (error) throw error;
console.log('Admin account was succesfully set up');
res.json({ success: true });
})
}Метод
setup позволяет создать учётную запись администратора, нужную для отладочных целей. В готовом приложении этой учётной записи быть не должно.Теперь, в том же файле, создадим метод, применяемый для тестовых целей, позволяющий вывести список всех пользователей, которые зарегистрировались в приложении, и нужный для проверки механизмов аутентификации:
api.index = (User, BudgetToken) => (req, res) => {
const token = BudgetToken;
if (token) {
User.find({}, (error, users) => {
if (error) throw error;
res.status(200).json(users);
});
} else return res.status(403).send({ success: false, message: 'Unauthorized' });
}Далее, создадим метод
signup, который понадобится позже. Он предназначен для регистрации новых пользователей:api.signup = (User) => (req, res) => {
if (!req.body.username || !req.body.password) res.json({ success: false, message: 'Please, pass a username and password.' });
else {
const newUser = new User({
username: req.body.username,
password: req.body.password,
clients: []
});
newUser.save((error) => {
if (error) return res.status(400).json({ success: false, message: 'Username already exists.' });
res.json({ success: true, message: 'Account created successfully' });
})
}
}
module.exports = api;Тут проверяется, при попытке регистрации нового пользователя, заполнены ли поля
username и password, а если это так, то, при условии, что введено допустимое имя пользователя, создаётся новый пользователь.На данном этапе работы над приложением будем считать, что методы API для работы с пользователями готовы.
Файл BudgetManagerAPI/app/routes/user.js
Теперь создадим файл
user.js в папке BudgetManagerAPI/app/routes и запишем в него следующий код:const passport = require('passport'),
config = require('@config'),
models = require('@BudgetManager/app/setup');
module.exports = (app) => {
const api = app.BudgetManagerAPI.app.api.user;
app.route('/api/v1/setup')
.post(api.setup(models.User))
app.route('/api/v1/users')
.get(passport.authenticate('jwt', config.session), api.index(models.User, app.get('budgetsecret')));
app.route('/api/v1/signup')
.post(api.signup(models.User));
}Здесь мы импортируем библиотеку
passport для организации аутентификации, подключаем конфигурационный файл для настройки параметров сессии, и подключаем модели, благодаря чему можно будет проверить, имеет ли пользователь право работать с конечными точками API.Испытания
Проверим то, что мы создали, предварительно запустив сервер приложения и сервер базы данных. А именно, если перейти по адресу http://localhost:3001/, то в окне терминала, где запущен сервер, можно будет увидеть сведения о запросе (там должно быть 200, что означает, что запрос прошёл успешно), и данные о времени ответа. Выглядеть это будет примерно так:

Приложение-клиент, то есть — браузер, должно вывести обычную страницу с текстом «Budget Manager API».
Проверим теперь маршрут
route, доступ к которому можно получить по адресу http://localhost:3001/api/v1/auth.В окне сервера появится сообщение о запросе GET со статусом 404 (это говорит о том, что с сервером связаться удалось, но он не может предоставить то, что нам нужно) и о времени ответа.

Происходит это из-за того, что мы используем данную конечную точку API только для POST-запросов. Серверу нечего ответить, если мы выполняем GET-запрос.
Проверим маршруты
user, перейдя по адресу http://localhost:3001/api/v1/users. Сервер сообщит о методе GET со статусом 401. Это указывает на то, что запрос не был обработан, так как у нас недостаточно привилегий для работы с целевым ресурсом. Клиент выдаст страницу с текстом «Unauthorized».Всё это позволяет судить о том, что система аутентификации работает, однако, тут возникает вопрос о том, как проверить методы входа в систему, если у нас пока даже нет формы регистрации.
Один из способов решить эту проблему заключается в использовании программы Postman. Её можно либо загрузить и установить как обычное приложение, либо пользоваться ей формате расширения для браузера Chrome.
Тестирование приложения с использованием Postman
Для начала подключимся к конечной точке
setup для создания учётной записи администратора. В интерфейсе Postman это будет выглядеть так:
В поле для адреса введём
http://localhost:3001/api/v1/setup, изменим тип запроса на POST и нажмём кнопку Send. В JSON-ответе сервера должно присутствовать сообщение "success": true.Теперь попытаемся войти в систему с учётной записью администратора.

Для этого воспользуемся POST-запросом к конечной точке
http://localhost:3001/api/v1/auth, на закладке Body зададим ключи username и password с одним и тем же значением admin и нажмём кнопку Send.Ответ сервера должен выглядеть так, как показано на рисунке ниже.

Далее, получим список пользователей системы.

Для этого скопируем значение ключа
token, воспользуемся GET-запросом, введя в поле адреса http://localhost:3001/api/v1/users, после чего добавим, на закладке Headers, новый заголовок Authorization со значением вида Bearer token (вместо token надо вставить токен, скопированный из ранее полученного ответа сервера). Там же добавим заголовок Content-Type со значением application/x-www-form-urlencoded и нажмём Send.В ответ должен прийти JSON-массив, в котором, в нашем случае, будут сведения лишь об одном пользователе, которым является администратор.

Проверим теперь метод регистрации нового пользователя,
signup.
Для этого откроем новую вкладку, настроим POST-запрос к конечной точке
http://localhost:3001/api/v1/signup, на закладке Body выберем переключатель x-www-form-urlencoded, введём ключи username и password со значениями, отличающимися от admin, и нажмём Send. Если всё работает как надо, в ответ должно прийти следующее:
Теперь, если мы вернёмся к вкладке
Postman, на которой обращались к http://localhost:3001/api/v1/users для получения списка пользователей, и нажмём Send, в ответ должен прийти массив из двух объектов, представляющих администратора и нового пользователя.
Итоги
На этом мы завершаем первую часть данной серии. Здесь вы узнали о том, как, с чистого листа, создать Node.js-приложение и настроить простую JWT-аутентификацию. В следующей части приступим к разработке пользовательского интерфейса приложения с использованием Vue.js.
Уважаемые читатели! Как по-вашему, подойдёт ли способ аутентификации пользователей, предложенный автором, для использования в продакшне?
xakepmega
github.com/icebob/vue-express-mongo-boilerplate вот схожий с тем что описан в статье boilerplate