Таблица лидеров. Часть 1.

На этом уроке, состоящем из нескольких частей, мы создадим простую игру Phaser 3 с аутентификацией и таблицей лидеров. Для нашей игры мы собираемся создать пользовательских вход/регистрацию с помощью Node.js, Express и MongoDB. После того, как игрок войдет в нашу игру, он сможет просматривать таблицу лидеров и отправлять новые рекорды в базу данных. Наконец, наш сервер также будет отвечать за размещение нашей игры Phaser. Цель этого руководства - научить вас основам добавления аутентификации пользователей в вашу игру и тому, как создать таблицу лидеров. Вы научитесь:

  • Создавать простой сервер с помощью Node.js и Express;
  • Настройки аутентификации пользователей с использованием MongoDB, Passport и JWT;
  • Защита маршрутов сервера с помощью промежуточных обработчиков (middleware) для аутентификации;
  • Создавать таблицу лидеров, используя данные из API
  • Разрешать пользователю сбросить пароль.

Вы можете скачать все файлы, связанные с исходным кодом 1 части здесь.

Требования к руководству В этом руководстве мы будем использовать Node.js и npm для установки необходимых пакетов для этого проекта. Для того, чтобы следовать этому руководству, вам необходимо локально установить Node.js и NPM или получить доступ к среде, в которой они уже установлены. Мы также будем использовать командную строку(Windows)/Терминал(Mac, Linux) для установки необходимых пакетов и запуска/остановки нашего Node-сервера.

Наличие опыта работы с этими инструментами приветствуется, но для этого руководства это не обязательно. Мы не будем рассказывать, как установить эти инструменты, поскольку основное внимание в этом руководстве уделяется созданию таблицы лидеров с помощью Phaser. Наконец, вам понадобится IDE или текстовый редактор для редактирования кода.

Чтобы установить Node.js, щелкните здесь и выберите версию LTS. Вы можете загрузить и использовать текущую версию, однако для большинства пользователей рекомендуется версия LTS. Когда вы устанавливаете Node.js, также будет установлен NPM на вашем компьютере. После установки этих инструментов вы можете переходить к следующей части.

Данное руководство тестировалось на версии v10.13.0. LTS Node.js Вы можете проверить свою версию Node, запустив node -v в терминале. Рекомендуется использовать эту или более новую версию, когда будете следовать инструкциям.

Наконец, в этом руководстве мы будем использовать MongoDB Atlas для нашей базы данных. Вы можете использовать его локальную версию или другое облачное решение для своей базы данных, но это выходит за рамки данного руководства.

Давайте начнем!

Для нашей базы данных мы будем использовать MongoDB, а в этом руководстве для размещения нашей базы данных мы будем использовать облачный сервис Atlas. Он предлагает бесплатный кластер хранилища 512 МБ для всех пользователей, которые создают учетную запись, и не требует какой-либо платежной информации для создания вашей учетной записи.

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

Чтобы создать учетную запись и получить бесплатный кластер посетите этот URL-адрес: MongoDB Atlas и заполните форму регистрации. После того, как вы заполнили все данные, нажмите Get Started Free кнопку. Вы попадете на экран, где можете выбрать бесплатный кластер. Нажмите кнопку Create a cluster в области Shared Clusters. В этом руководстве мы будем использовать настройки по умолчанию для уровня бесплатного использования AWS. Нажмите зеленую кнопку Create Cluster, чтобы MongoDB Altas начал подготовку вашего кластера. Для полной подготовки кластера потребуется несколько минут. Как только ваш кластер станет доступен, нам нужно кое-что настроить несколько прежде чем мы подключимся к нашей новой базе данных. Во-первых, мы собираемся настроить, какие IP-адреса включены в белый список для подключения к нашему кластеру. По умолчанию любой сможет подключиться к кластеру, если у него есть правильное имя пользователя и пароль для базы данных. Добавление вашего IP-адреса в белый список поможет сделать ваш кластер более безопасным.

Если у вас динамические IP-адреса, у вас есть следующие варианты:

  1. Вы можете использовать Atlas Public API для динамического добавления и удаления IP-адресов из белого списка. Чтобы ознакомиться с документацией MongoDB Atlas по настройке доступа к Atlas API, щелкните здесь. Данный метод уже не поддерживается и работает только со старыми ключами.
  2. Вы можете использовать пиринг VPC (эта функция недоступна для бесплатных кластеров), чтобы связать кластер Atlas с существующим VPC. Для подробной документации по настройке однорангового соединения VPC в MongoDB Atlas щелкните здесь.
  3. Или вы можете установить свой белый список на 0.0.0.0/0, чтобы разрешить весь Интернет в ваш белый список IP. Для просмотра документации MongoDB Atlas по добавлению записей в белый список IP-адресов щелкните здесь.

Обратите внимание, что добавление 0.0.0.0/0 в белый список кластера может подвергнуть кластер атакам типа «отказ в обслуживании». Также имейте в виду, что Heroku использует динамические IP-адреса, поэтому вам нужно будет добавить 0.0.0.0/0 в белый список при использовании Heroku для подключения к вашему кластеру Atlas.

Чтобы добавить свой IP-адрес, щелкните в разделе Security кнопку Network Access. Вы должны быть на вкладке IP Whitelist. Затем нажмите зеленую кнопку Add IP Address и в появившемся модальном окне нажмите кнопку Add Current IP Address (Получить текущий IP-адрес) или введите свой IP-адрес в текстовое поле. В случае динамического IP-адреса можно нажать кнопку ALLOW ACCESS FROM ANYWHERE (Предоставить доступ всем). Наконец, нажмите кнопку Confirm (Подтвердить), чтобы сохранить изменения. Настройки станут активными через минуту или две. Как только этот параметр будет включен, мы создадим пользователя базы данных. Чтобы создать пользователя базы данных, в разделе Security щелкните кнопку Database Access. Вы должны быть на вкладке Database User. Затем нажмите кнопку Add New User и в появившемся модальном окне введите имя пользователя вашей базы данных и введите пароль или нажмите кнопку Autogenerate secure password (Сгенерировать безопасный пароль), чтобы ввести безопасный пароль. Для остальных настроек оставьте параметры по умолчанию, а затем нажмите кнопку Add User, чтобы создать своего пользователя. После того, как эти изменения будут развернуты в вашем кластере, вы сможете подключиться к своей новой базе данных. Чтобы подключиться к вашей базе данных, вам нужно будет получить строку подключения URI для вашего кластера. Для этого в разделе DATA STORAGE щелкните на конпку Clusters, а затем нажмите конпку connect. В появившемся модальном окне выберите пункт Connect Your Application. Флажок Include full driver code example должен быть снят. Это покажет вам строку подключения URI для вашего кластера с паролем, установленным на <PASSWORD>. Вам нужно будет обновить эту часть строки паролем, который вы создали ранее для пользователя базы данных.

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

Первое, что мы добавим в папку проекта - это файл среды, который мы будем использовать для хранения конфиденциальных данных для нашего проекта. В созданной вами папке создайте новый файл с именем .env и в этом файле добавьте следующий код и замените его placeholder строкой подключения URI MongoDB, которую мы только что получили из MongoDB Atlas:

MONGO_CONNECTION_URL=placeholder

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

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

В случае, если вы будете использовать систему контроля версий с кодом вашего проекта (например, git), рекомендуется убедиться, что этот файл не фиксируется с вашим исходным кодом, и обычно лучше добавить файл .env в список игнорируемых файлов ( .gitignore при использовании git). В этом руководстве мы не будем использовать систему контроля версий.

Затем, поскольку мы будем использовать внешние зависимости в нашем проекте, нам нужно будет создать файл package.json для отслеживания этих зависимостей. Для этого откройте окно терминала/командной строки и перейдите в папку своего проекта. Оказавшись там, выполните следующую команду:

 npm init -f

Эта команда создаст файл package.json с некоторыми значениями по умолчанию. А пока оставим эти значения в покое.

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

npm install --save express body-parser dotenv

Эта команда установит пакеты express, body-parser и dotenv в наш проект, а, передавая флаг save в команду npm install NPM автоматически добавит эти пакеты в наш файл package.json. Пакет express является основой для веб - приложений Nodejs, с помощью которой легко создавать веб-сервера для размещения своих API и статические файлы. Пакет body-parser необходим для разбора тела запроса, который отправляется в наш express-сервер.

Установив необходимые зависимости, мы можем создать наш сервер. Для этого создайте новый файл с именем app.js и добавьте в него следующий код:

// Читаем параметры в нашем файле .env и делаем эти значения доступными как переменные среды
require('dotenv').config();

const express = require('express');
const bodyParser = require('body-parser');

// Создаем экземпляр приложения express
const app = express();

// Обновляем настройки express
app.use(bodyParser.urlencoded({ extended: false })); // разбираем application/x-www-form-urlencoded
app.use(bodyParser.json()); // разбираем application/json

// Главный маршрут
app.get('/status', (req, res, next) => {
  res.status(200);
  res.json({ 'status': 'ok' });
});

// Отлавливаем все остальные маршруты
app.use((req, res, next) => {
  res.status(404);
  res.json({ message: '404 - Not Found' });
});

// Обработка ошибок
app.use((err, req, res, next) => {
  res.status(err.status || 500);
  res.json({ error : err });
});

// Начинаем прослушивать сервер на выбранном порту
app.listen(process.env.PORT || 3000, () => {
  console.log(`Server started on port ${process.env.PORT || 3000}`);

В приведенном выше коде мы сделали следующее:

  • С помощью dotenv читаем настройки в нашем .env-файле и делаем эти значения доступными как переменные среды. Рекомендуется вызывать этот метод как можно раньше в своем приложении.
  • Затем мы загрузили остальные модули, которые нам понадобятся для нашего приложения.
  • Далее мы создали экземпляр express-приложения и сказали этому приложению использовать загруженный ранее модуль bodyParser. Используя модуль bodyParser мы сможем анализировать входящие полезные данные из тела POST.
  • Затем мы создали GET-маршрут /status, который наш сервер будет прослушивать, и когда эта конечная точка будет вызвана, сервер вернет ответ 200.
    • Чтобы создать маршрут, нам сначала нужно сообщить express какой HTTP-метод поддерживается для этого маршрута, и мы делаем это, вызывая соответствующий метод app, например, get или post.
    • Затем в вызове метода мы передаем два аргумента: первый - это маршрут, который мы хотим сделать доступным ( в нашем случае /status), а второй аргумент - это функция обратного вызова, которая будет вызываться при вызове данного маршрута.
    • Эта функция обратного вызова при вызове получит три аргумента:
      • req - объект запроса, который будет содержать все метаданные для запроса. Некоторые из этих данных включают заголовки, текст, параметры строки запроса и т. д.
      • res - объект ответа, возвращаемый вызывающей стороне. Этот объект позволяет нам установить код состояния, тип ответа и возвращаемую полезную нагрузку.
      • next - Может использоваться для вызова следующего промежуточного программного обеспечения в цепочке, если мы не закончили обработку запроса. (Конвейерная обработка)
  • Затем мы создали два обработчика промежуточного программного обеспечения для нашего express-приложения: обработчик ошибок и обработчик 404.
    • Промежуточное ПО обработчика (middleware) ошибок уникально, потому что оно получает четыре аргумента вместо трех, а этот новый аргумент является отправленной ошибкой.
    • Промежуточное ПО обработчика (middleware) 404 будет вызываться последним, если никакое другое middleware не вернуло ответ. Middleware действует как универсальное средство, если пользователь пытается вызвать какие-либо маршруты, которые мы явно не определили.
  • Наконец, мы сказали нашему серверу начать прослушивание порта 3000, или, если установлена переменная среды PORT, приложение будет использовать ее.

Чтобы протестировать наше приложение, запустите в терминале следующую команду:

node app.js

Вы должны увидеть сообщение о запуске сервера на 3000 порту. Если вы в своем браузере зайдете по адресу http://localhost:3000/status, то вы должны увидеть созданное нами сообщение о статусе. Наконец, если вы посетите любой другой маршрут, например http://localhost:3000/status2, то вы должны увидеть сообщение 404 о том, что маршрут не найден.

Теперь, когда у нас есть express-сервер, мы собираемся переместить наш маршрут status в новый файл. Поступая так, мы сделаем наш код более организованным и упростим поддержку кода по мере роста нашего проекта. Для этого создайте новую папку в корне вашего проекта с именем routes. А затем в папке routes создайте новый файл с именем main.js и добавьте в этот файл следующий код:

const express = require('express');

const router = express.Router();

router.get('/status', (req, res, next) => {
  res.status(200);
  res.json({ 'status': 'ok' });
});

module.exports = router;

В приведенном выше коде мы создали новый экземпляр класса express.Router, который позволяет группировать обработчики маршрутов для определенной части сайта и получать к ним доступ через общий префикс маршрута. Данные промежуточные запросы действуют как мини-экспресс-приложение, которое мы можем импортировать в наше основное приложение. Итак, добавив конечную точку /status к этому маршрутизатору, мы можем удалить данную логику из файла app.js и вместо этого сослаться на новый маршрутизатор.

Для этого откройте файл app.js и добавьте следующий код в начале файла рядом другими строками импорта:

const routes = require('./routes/main');

Затем замените следующий код:

app.get('/status', (req, res, next) => {
  res.status(200);
  res.json({ 'status': 'ok' });
});

на этот:

app.use('/', routes);

Теперь, если вы сохраните изменения в коде, остановите сервер и перезапустите его, вы все равно сможете перейти к конечной точке /status.

Установка нового маршрутизатора на этом завершает первую часть данного руководства. Во второй части мы сделаем следующее:

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

Надеюсь вам эта статья понравилась и вы сочли ее полезной!

Оригинал