Автор оригинала: FreeCodeCamp Community Member.
Зафар Алема
Написание логики Backend для любого проекта в эти дни довольно просты, благодаря полный стек JavaScript. Это особенно так с введением десятков фреймворков как для клиентской боковой, так и для реализации Server Side.
Один из самых популярных ody.js frameworks – Express.js Отказ Он предлагает легкий подход к созданию приложений в разных масштабах. Однако, как проект растет, в какой-то момент становится трудно масштабироваться.
Многие разработчики имеют тенденцию продолжать добавлять новые файлы маршрута и модели для новых сервисов и конечных точек API. Этот подход работает, но это действительно делает его трудолюбивым для будущих инженеров для масштабирования и добавления новых услуг.
В этом блоге я собираюсь создать систему входа в систему и регистрацию, которая использует аутентификацию JWT с масштабируемой архитектурой. Для тех, кто предпочитает направиться в код, идти вперед и клонировать этот репозиторий.
В этом блоге будет четыре части.
- Основная архитектура Настройка
- Регистрация
- Авторизоваться
- Щиток приборов
Этот блог предполагает, что вы Уже установлен Node.js в вашей системе. Давайте попадем в первый шаг – основная настройка архитектуры.
Основная архитектура Настройка
Первые вещи сначала сделайте новый каталог в вашей файловой системе и позвоните в него автор (или все, что вам нравится).
mkdir auth
Сейчас CD в этот каталог и создать файл package.json. Добавьте линии ниже в нее.
{ "name": "auth", "version": "0.0.0", "private": true, "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "bcrypt": "latest", "body-parser": "^1.18.2", "cookie-parser": "~1.4.3", "express": "~4.15.5", "jsonwebtoken": "^8.1.1", "mongoose": "^5.0.3", "lodash": "^4.17.11", "morgan": "^1.9.0", "passport": "^0.4.0", "passport-jwt": "^3.0.1", "serve-favicon": "~2.4.5" } }Самая важная часть файла выше – зависимости имущество. Это зависимости, необходимые для проекта. Они будут использоваться в качестве промежуточного программного обеспечения позже в этом блоге.
Теперь идите вперед и запустите команду ниже, чтобы установить все эти зависимости. Вам может потребоваться подождать несколько секунд.
npm install
Как только он устанавливает все вышеуказанные зависимости, продолжайте и создайте index.js Файл в вашей корневой папке, как ниже:
touch index.js
Этот конкретный файл отвечает только за запуском сервера. Для этого добавьте ниже код в него:
'use strict';
const server = require('./server')();const config = require('./configs');const db = require('./configs/db');server.create(config, db);server.start();
Как видите, этот файл требует трех файлов:
- сервер
- конфигурация
- дб
Мы создадим их следующим.
Код выше тогда вызывает создать Способ на серверном модуле. Наконец, он называет Начать Метод, который запускает сервер.
1. Создайте папку сервера
mkdir server
Однажды сделано, CD в эту папку и создать еще одну index.js файл.
touch index.js
Теперь добавьте код ниже в этот файл:
'use strict';
const express = require('express');const bodyParser = require('body-parser');const logger = require('morgan');const mongoose = require('mongoose');const passport = require('passport');const cookieParser = require('cookie-parser');module.exports = function() { let server = express(), create, start; create = function(config, db) { let routes = require('./routes'); // Server settings server.set('env', config.env); server.set('port', config.port); server.set('hostname', config.hostname); // Returns middleware that parses json server.use(bodyParser.json()); server.use(bodyParser.urlencoded({ extended: false })); server.use(cookieParser()); server.use(logger('dev')); server.use(passport.initialize()); mongoose.connect(db.database); require('../configs/passport')(passport);// Set up routes routes.init(server); };
start = function() { let hostname = server.get('hostname'), port = server.get('port'); server.listen(port, function () { console.log('Express server listening on - http://' + hostname + ':' + port); }); }; return { create: create, start: start };};В этом файле мы сначала потребуются все зависимости, необходимые для этого проекта. Обратите внимание, что в этот файл можно добавить больше зависимостей.
Затем мы экспортируем анонимную функцию из этого модуля, используя Module.exports Отказ Внутри этой функции создайте три переменных: Сервер , создать и Начать Отказ
Сервер Переменная предназначена для сервера Express.js. Итак, позвоните Express () Функция и присвоить это для Сервер Отказ Мы назначим анонимные функции для создать и Начать Переменные.
Теперь пришло время написать создать Функция с двумя параметрами: config . и дБ Отказ
Затем установите несколько настроек сервера, используя функцию Server.use () i.e. env, port и hostname. Тогда используйте CookieParser, BodyParser, регистратор и паспорт подразделение. Затем подключитесь к мангуст База данных и, наконец, требуется файл конфигурации паспорта и вызовите его с требуемым паспортом.
Passport Mardware используется для аутентификации, которую мы будем использовать позже в этом блоге. Чтобы узнать больше об этом, нажмите здесь Отказ
Теперь пришло время для конечных точек API I.E. Маршруты. Просто позвоните init Функция на маршрутах и прохождении Сервер в это.
Далее, напишите Начать функция. Установить Имя хоста и порт и начать сервер с слушать Команда внутри этой функции.
Затем верните оба создать и Начать Функции, чтобы сделать их доступными для других модулей для использования.
2. Создайте папку конфигурации
На корневом уровне создайте Конфиги папка:
mkdir configs
CD в эту папку и создать файл index.js:
touch index.js
Добавьте код ниже в файл index.js:
'use strict';
const _ = require('lodash');const env = process.env.NODE_ENV || 'local';const envConfig = require('./' + env);let defaultConfig = { env: env};module.exports = _.merge(defaultConfig, envConfig);
Теперь создайте файл local.js:
touch local.js
Откройте его и добавьте код ниже:
'use strict';
let localConfig = { hostname: 'localhost', port: 3000};module.exports = localConfig;
Это тоже просто. Мы создаем localconfig объект и добавление нескольких свойств, таких как имя хоста и порт . Затем экспортируйте его, чтобы использовать его, как мы делаем в ./index.js файл.
3. Теперь создайте базу данных
touch db.js
Откройте db.js в вашем любимом редакторе и вставьте в него код ниже.
module.exports = { 'secret': 'putsomethingsecretehere', 'database': 'mongodb://127.0.0.1:27017/formediumblog'};Мы экспортируем объект JavaScript со свойствами Секрет и база данных Отказ Они используются для подключения с базой данных MongoDB с помощью промежуточного программного обеспечения под названием Mongoose.
Создание приложения
Теперь мы сделаем с базовой настройкой нашего проекта, времени для веселых вещей!
CD в Сервер Папка и создать следующие папки:
mkdir controllers models routes services
Во-первых, мы охватим маршруты папка. Эта папка используется для добавления всех конечных точек, доступных для использования на стороне клиента. Прежде всего идти вперед и создать index.js Файл сначала внутри маршруты папка.
touch index.js
И поставьте ниже код в этот файл:
'use strict';
const apiRoute = require('./apis');function init(server) { server.get('*', function (req, res, next) { console.log('Request was made to: ' + req.originalUrl); return next(); }); server.use('/api', apiRoute);}module.exports = { init: init};Во-первых, требуют APIROUTE Папка, которую мы собираемся создать дальше. Эта папка будет содержать другую папку с номером версии API I.E. v1 Отказ
Второй создать init функция. Мы называем эту функцию из Сервер/index.js Файл внутри создать функция внизу и прохождение Сервер как параметр. Он просто получает все маршруты и возвращает следующую функцию обратного вызова.
Затем используйте APIROUTE что мы требуем выше. Наконец, экспортируйте функцию init, чтобы сделать эту функцию доступной в остальной части проекта.
Теперь идите вперед, создайте API папка. Внутри этой папки создают файл index.js Отказ
mkdir apistouch index.js
Вставьте следующий код в index.js файл.
'use strict';
const express = require('express');const v1ApiController = require('./v1');let router = express.Router();
router.use('/v1', v1ApiController);module.exports = router;
Этот файл требует Экспресс и папка версий API I.E. v1 Отказ Затем создайте маршрутизатор и сделайте /v1 Конечная точка, используя Маршрутизатор. Используйте () метод. Наконец экспортируйте маршрутизатор.
Пришло время создать APIS/V1.JS файл. Вставьте следующий код внутри v1.js файл:
'use strict';
const registerController = require('../../controllers/apis/register');const express = require('express');let router = express.Router();
router.use('/register', registerController);module.exports = router;
Нам нужно зарегистрировать контроллер и Express.js и создать маршрутизатор. Тогда нам нужно разоблачить Регистрация API конечные точки для использования клиентов. Наконец, мы должны экспортировать маршрутизатор из этого модуля.
Это файл, который мы собираемся продолжать модифицировать. Мы потребуем больше контроллеров здесь, когда мы их создаем.
Теперь мы сделаем с папкой маршрутов, и настало время для папки контроллеров. Продолжай и компакт-диск в эту папку и создайте папку API Отказ
mkdir apis
Теперь, когда у нас есть папка APIS внутри контроллеры Мы собираемся создать следующие три контроллера и их соответствующую Услуги Отказ
- Основная архитектура Настройка
- Регистрация
- Авторизоваться
- Щиток приборов
Во-первых, это Registercontroller Отказ Продолжайте и создайте ниже файл.
touch register.js
Откройте этот файл в своем любимом редакторе и вставьте в него код ниже:
'use strict';
const express = require('express');const registerService = require('../../services/authentication/register');let router = express.Router();
router.post('/', registerService.registerUser);module.exports = router;
Сначала это требуется Express.js и Регистрация Сервис (который мы собираемся написать позже). Затем создайте маршрутизатор, используя выражать. Маршрутизатор () Способ и сделать запрос на пост '/' дорожка. Затем позвоните методу RegisterUser на RegisterService (который мы собираемся написать позже). Наконец, экспортируйте маршрутизатор из этого модуля.
Теперь нам нужно требовать этого контроллера внутри Маршруты/API/V1.js Файл, который мы уже сделали.
Теперь регистрация контроллера сделано. Пришло время добраться до Услуги папка. CD в эту папку и создать Аутентификация папка. Первые вещи сначала, CD в Аутентификация и создать Register.js файл.
touch register.js
Затем откройте Register.js Файл и вставьте в него код ниже:
'use strict';
const express = require('express');const User = require('../../models/User');const httpMessages = { onValidationError: { success: false, message: 'Please enter email and password.' }, onUserSaveError: { success: false, message: 'That email address already exists.' }, onUserSaveSuccess: { success: true, message: 'Successfully created new user.' }}// Register new usersfunction registerUser(request, response) { let { email, password } = request.body; if (!email || !password) { response.json(httpMessages.onValidationError); } else { let newUser = new User({ email: email, password: password }); // Attempt to save the user newUser.save(error => { if (error) { return response.json(httpMessages.onUserSaveError); } response.json(httpMessages.onUserSaveSuccess); }); }}module.exports = { registerUser: registerUser};В Регистрация Сервис, сначала мы требуем Expressjs и Пользователь модель. Тогда мы создаем объект JavaScript I.E. httpmessages Что в основном является список всех сообщений, которые мы собираемся отправлять клиентам через API, когда клиент отправляет запрос.
Тогда функция зарегистрирован который фактически выполняет процесс регистрации. Перед тем, как сохранить пользователь, есть чек, если пользователь предоставил свой адрес электронной почты и пароль. Если они сделали, создали Newuser, используя Новый Ключевое слово с предоставленной электронной почтой и паролем.
Тогда просто позвоните Сохранить Функция на Newuser Чтобы сохранить этот пользователь в базе данных и отправить соответствующий ответ, используя ответ. Джусон .
Наконец экспортируйте эту функцию, используя Module.exports использовать его в остальной части проекта. Мы используем это внутри Контроллеры/Register.js файл.
Прежде чем тестировать это, чтобы увидеть, работает ли он, сначала нам нужно создать Пользователь модель. Идти вперед создать файл User.js внутри модели папка.
touch User.js
И вставьте этот код в указанный выше файл:
const mongoose = require('mongoose');const bcrypt = require('bcrypt');const UserSchema = new mongoose.Schema({ email: { type: String, lowercase: true, unique: true, required: true }, password: { type: String, required: true }, role: { type: String, enum: ['Client', 'Manager', 'Admin'], default: 'Client' }});UserSchema.pre('save', function(next) { let user = this; if (this.isModified('password') || this.isNew) { bcrypt.genSalt(10, (err, salt) => { if (err) { console.log(err); return next(err); } bcrypt.hash(user.password, salt, (err, hash) => { if (err) { console.log(err); return next(err); } user.password = hash; next(); }); }); } else { return next(); }});// Create method to compare password input to password saved in databaseUserSchema.methods.comparePassword = function(pw, cb) { bcrypt.compare(pw, this.password, function(err, isMatch) { if (err) { return cb(err); }cb(null, isMatch); });};
module.exports = mongoose.model('User', UserSchema);Прежде всего, требуют мангуста и BCRYPT модули. Mongoose используется для создания схемы Mongodb, тогда как Bcrypt используется для шифрования паролей, прежде чем хранить их в базу данных.
Создать Userschema. с Электронная почта, пароль и роль характеристики. Затем перед сохранением пользователя выполните некоторые проверки перед перемешиванием пароля.
Окончательная функция состоит в том, чтобы сравнить пароли. Он сравнивает пароль пользователя с хешированным паролем в базе данных.
Теперь, чтобы проверить этот код, Откройте Postman (если вы не установили почтальон, идут вперед, установите его из здесь ). Откройте почтальон и введите URL ниже:
http://localhost:3000/api/v1/register
Выберите пост как запрос, выберите вкладку «Тело» и Форма-орленкадированный и введите адрес электронной почты и пароль. Нажмите кнопку «Отправить», и вы должны увидеть сообщение ниже успеха.
Теперь деталь реестра сделана.
- Основная архитектура Настройка
- регистр
- Авторизоваться
- Щиток приборов
Настало время сосредоточиться на входе. Создать login.js Файл внутри Контроллеры папка.
touch login.js
Теперь откройте его и вставьте следующий код:
'use strict';
const express = require('express');const loginService = require('../../services/authentication/login');let router = express.Router();
router.post('/', loginService.loginUser);module.exports = router;
Опять же просто и так же, как модуль реестра: после импорта Express.js и логинсервис Мы создаем маршрутизатор и сделаем запрос на почту на корневой путь '/' с Логин Функция обратного вызова на Логинсервис Отказ Наконец экспортируйте маршрутизатор.
Пришло время потребовать Logincontroller В Маршруты/API/V1.js файл. Ваш v1.js Файл должен выглядеть следующим образом.
'use strict';
const registerController = require('../../controllers/apis/register');const loginController = require('../../controllers/apis/login');const express = require('express');let router = express.Router();
router.use('/register', registerController);router.use('/login', loginController);module.exports = router;
Теперь для сервиса входа в систему, создайте login.js Файл внутри Услуги/Аутентификация/ :
touch login.js
И вставьте код ниже в этот файл:
'use strict';
const express = require('express');const apiRoutes = express.Router();const jwt = require('jsonwebtoken');const passport = require('passport');const db = require('../../../configs/db');const User = require('../../models/User');const httpResponse = { onUserNotFound: { success: false, message: 'User not found.' }, onAuthenticationFail: { success: false, message: 'Passwords did not match.' }}function loginUser(request, response) { let { email, password } = request.body;User.findOne({ email: email }, function(error, user) { if (error) throw error; if (!user) { return response.send(httpResponse.onUserNotFound); } // Check if password matches user.comparePassword(password, function(error, isMatch) { if (isMatch && !error) { var token = jwt.sign(user.toJSON(), db.secret, { expiresIn: 10080 }); return response.json({ success: true, token: 'JWT ' + token }); }response.send(httpResponse.onAuthenticationFail); }); });};
module.exports = { loginUser: loginUser};Сначала требуют таких необходимых модулей, как: Express.js, jsanwebtken, passport, db и модель пользователя Отказ Создайте объект JavaScript, который имеет список сообщений, которые будут отправлены на стороне клиента, когда HTTP-запрос сделан на эту услугу.
Создайте функцию LoginuSer, а внутри, которые создают пару переменных i.e. Email и пароль, и назначьте электронное письмо и пароль, отправленные пользователем на эти переменные, которые находятся в request.body Отказ
Затем используйте findone () Метод на Пользователь Модель, чтобы найти использование на основе электронного письма, отправленного от клиента пользователем. Функция обратного вызова findone () Принимает 2 параметра, Ошибка и пользователь Отказ Сначала проверьте, если вышеупомянутое findone () Метод бросает любую ошибку – если она будет затем бросить ошибку.
Затем выполните проверку: если пользователь не найден, то отправьте правильный ответ с сообщением из списка сообщений, которые мы объявили выше в этом модуле.
Затем сравните пароль, который пользователь отправлен с одним в базе данных, используя Сравнить Функция, которую мы написали в Пользователь Модель ранее в этом блоге.
Если пароль совпадает, и он не возвращает ошибку, то мы создаем токен, используя jsonwebkoken Модуль и верните этот токен, используя json.response () клиенту. В противном случае мы отправляем аутентификацияfail сообщение.
Наконец экспортировать Логин Функция с Exports.module Так что мы можем использовать его в наших контроллерах и где-нибудь еще.
Пришло время проверить функциональность входа в систему. Вернитесь в почтальон и на этот раз замените Регистрация с Вход как конечная точка API в URL. Введите адрес электронной почты и пароль и нажмите кнопку «Отправить». Вы должны быть в состоянии получить токен. Продолжайте и скопируйте это в буфер обмена, потому что вы будете использовать его позже, чтобы получить доступ к приборной панели.
- Основная архитектура Настройка
- регистр
- Авторизоваться
- Щиток приборов
Теперь пришло время Dashboard.js файл. Создать Dashboard.js Файл внутри Контроллеры папка.
touch dashboard.js
И откройте его и вставьте следующий код:
'use strict';
const passport = require('passport');const express = require('express');const dashboardService = require('../../services/dashboard/dashboard');let router = express.Router();
router.get('/', passport.authenticate('jwt', { session: false }), dashboardService.getDashboard);module.exports = router;
Этот контроллер отличается в том смысле, что требует аутентифицированного доступа. То есть только вошедший пользователь может получить доступ к сервису приборной панели и сделать разные HTTP-запросы.
По этой причине мы также импортируем паспорт, а для получения запроса мы используем Passport.authenticate () Функция на getdashboard услуга.
Снова нам нужно требовать DashboardController В Маршруты/API/V1.js файл. Ваш v1.js Файл должен выглядеть следующим образом:
'use strict';
const registerController = require('../../controllers/apis/register');const loginController = require('../../controllers/apis/login');const dashboardController = require('../../controllers/apis/dashboard');const express = require('express');let router = express.Router();
router.use('/register', registerController);router.use('/login', loginController);router.use('/dashboard', dashboardController);module.exports = router;
Теперь, когда DashboardController Доступно для использования клиентских запросов, пришло время создать соответствующий сервис. Перейдите в папку «Услуги» и создайте Приборная панель папка внутри нее. Создать Dashboard.js Файл и поставьте следующий код в этот файл.
'use strict';
function getDashboard(request, response) { response.json('This is from dashboard');}module.exports = { getDashboard: getDashboard}Никаких модных вещей происходит. Для демонстрационных целей я просто отвечаю на текстовое сообщение Это от приборной панели Отказ Затем экспортируйте этот метод, который будет использоваться в соответствующем контроллере, который мы уже достигли.
Теперь это время тестирования. Откройте почтальон и измените конечную точку URL на приборную панель. Нажмите на вкладку заголовков и добавьте Авторизация И вставьте JTW скопированные на предыдущем шаге, когда вы вошли в систему.
Вы должны увидеть сообщение Это от приборной панели как ответ.
Как видите, когда мы создаем новую услугу, нам нужен один контроллер для него, и мы можем продолжать добавлять новые услуги в архитектуру. Если вы хотите изменить версию API, а также сохранить текущий, просто добавьте новый v2.js Файл и перенаправить все запросы на эту конечную точку. Это один простой пример.
Я надеюсь, вам понравился этот блог и увидимся в следующий раз.
Обновление: если вы хотите реализовать свою сторону клиента, пожалуйста, Нажмите здесь где я использовал REACT.js для аутентификации с этим сервером.
Оригинал: “https://www.freecodecamp.org/news/writing-scalable-architecture-for-node-js-2b58e0523d7f/”