Изготовление сайтов в Донецке, ДНР. Локальная аутентификация с использованием паспорта в Node.js

 
 

Общим требованием при создании веб-приложения является реализация системы входа в систему, чтобы пользователи могли аутентифицировать себя, прежде чем получить доступ к защищенным представлениям или ресурсам. К счастью для тех, кто создает приложения Node, существует промежуточное ПО под названием Passport, которое можно добавить в любое веб-приложение на основе Express, чтобы обеспечить механизмы аутентификации всего несколькими командами.

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

Как всегда, весь код для этой статьи доступен для скачивания на GitHub.

Предпосылки

Чтобы следовать этому руководству, на вашем компьютере должны быть установлены Node и MongoDB.

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

MongoDB поставляется в различных редакциях. Нас интересует MongoDB Community Edition.

На домашней странице проекта есть отличная документация, и я не буду пытаться воспроизвести ее здесь. Скорее предложу вам ссылки на инструкции для каждой из основных операционных систем:

Установите MongoDB Community Edition в Windows

Установите MongoDB Community Edition на macOS

Установите MongoDB Community Edition на Ubuntu

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

Примечание. Вам не нужно вводить свое имя и адрес, чтобы загрузить MongoDB. При появлении запроса вы обычно можете закрыть диалоговое окно.

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

Стратегии аутентификации: сеанс против JWT

Прежде чем мы начнем, давайте кратко поговорим о вариантах аутентификации.

Многие современные онлайн-учебники выбирают аутентификацию на основе токенов с использованием веб-токенов JSON (JWT). Этот подход, пожалуй, самый простой и популярный в настоящее время. Он возлагает часть ответственности за аутентификацию на клиента и заставляет его подписывать токен, отправляемый с каждым запросом, чтобы пользователь оставался аутентифицированным.

Аутентификация на основе сеанса существует дольше. Этот метод передает вес аутентификации серверу. Он использует файлы cookie и видит, как приложение Node и база данных работают вместе, чтобы отслеживать состояние аутентификации пользователя.

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

Оба метода имеют свои преимущества и недостатки. Если вы хотите узнать больше о разнице между ними, эта ветка Stack Overflow может быть хорошим местом для начала.

Создание проекта

После установки всего необходимого программного обеспечения можно приступать к работе.

Мы начнем с создания папки для нашего приложения, а затем получим доступ к этой папке на терминале:

mkdir AuthApp

cd AuthApp

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

npm init

Вам будет предложено предоставить некоторую информацию для Node package.json. Просто продолжайте нажимать Return, чтобы принять конфигурацию по умолчанию (или используйте -yфлаг).

Настройка Экспресс

Теперь нам нужно установить Express. Перейдите в терминал и введите эту команду:

npm install express

Нам также потребуется установить промежуточное ПО body-parser, которое используется для анализа тела запроса, используемого Passport для аутентификации пользователя. И нам нужно будет установить промежуточное ПО экспресс-сессии.

Давайте сделаем это. Выполните следующую команду:

npm install body-parserexpress-session

Когда это будет сделано, создайте index.jsфайл в корневой папке вашего приложения и добавьте в него следующее содержимое:

/* EXPRESS SETUP */

const express = require ('express’) ;

const app = express () ;

app.use (express.static (__dirname));

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

const expressSession = require ('express-session’) ({

secret: 'secret’,

resave: false,

saveUninitialized: false

}) ;

app.use (bodyParser.json ());

app.use (bodyParser.urlencoded ({ extended: true }));

app.use (expressSession) ;

const port = process.env.PORT || 3000;

app.listen (port, () => console.log ('App listening on port ' + port));

Во- первых, мы requireвыражаем и создаем наше приложение Express, вызывая express (). Затем мы определяем каталог, из которого будут обслуживаться наши статические файлы.

В следующей строке мы видим requireпромежуточное ПО body-parser, которое поможет нам разобрать тело наших запросов. Мы также добавляем ПО промежуточного слоя для экспресс-сеансов, чтобы помочь нам сохранить файл cookie сеанса.

Как видите, мы настраиваем экспресс-сеанс с помощью secretподписи файла cookie идентификатора сеанса (вы должны выбрать здесь уникальное значение) и двух других полей, resave и saveUninitialized. Поле resaveпринудительно сохраняет сеанс обратно в хранилище сеансов, а saveUninitializedполе принудительно сохраняет «неинициализированный» сеанс в хранилище. Чтобы узнать о них больше, ознакомьтесь с их документацией, а пока достаточно знать, что для нашего случая мы хотим их сохранить false.

Затем мы используем process.env.PORTдля установки порта переменную порта среды, если она существует. В противном случае по умолчанию 3000будет использоваться порт, который мы будем использовать локально. Это дает вам достаточную гибкость, чтобы переключиться с разработки непосредственно на производственную среду, где порт может быть установлен поставщиком услуг, таким как, например, Heroku. Прямо под этим мы вызвали app.listen () с настроенной нами переменной порта и простым журналом, чтобы мы знали, что все работает нормально и какой порт прослушивает приложение.

Это все, что касается экспресс-настройки. Теперь дело за настройкой Passport.

Настройка паспорта

Сначала мы устанавливаем Passport с помощью следующей команды:

npm install passport

Затем нам нужно добавить следующие строки в конец index.jsфайла:

/* PASSPORT SETUP */

const passport = require ('passport’) ;

app.use (passport.initialize ());

app.use (passport.session ());

Здесь мы требуем passportи инициализируем его вместе с промежуточным программным обеспечением аутентификации сеанса непосредственно в нашем приложении Express.

Создание хранилища данных MongoDB

Поскольку мы предполагаем, что вы уже установили Mongo, вы сможете запустить оболочку Mongo с помощью следующей команды:

mongo

В оболочке введите следующую команду:

use MyDatabase;

Это просто создает хранилище данных с именем MyDatabase.

Оставьте терминал там; мы вернемся к этому позже.

Подключение Mongo к узлу с помощью Mongoose

Теперь, когда у нас есть база данных с записями в ней, нам нужен способ связи с ней из нашего приложения. Для этого мы будем использовать Mongoose. Почему бы нам просто не использовать простой Mongo? Что ж, как любят говорить разработчики Mongoose, A href="https://mongoosejs.com/docs/unstable/index.html"> на своем веб-сайте:

написание шаблонов проверки MongoDB, кастинга и бизнес-логики — это проблема.

Mongoose просто сделает нашу жизнь проще, а наш код — более элегантным.

Давайте продолжим и установим его с помощью следующей команды:

npm install mongoose

Мы также будем использоватьpassport -local-mongoose, что упростит интеграцию между Mongoose и Passport для локальной аутентификации. Он добавит поле hashи saltв нашу схему для хранения хешированного пароля и значения соли. Это здорово, так как пароли никогда не должны храниться в базе данных в виде простого текста.

Давайте установим пакет:

npm install passport-local-mongoose

Теперь нам нужно настроить Mongoose. Надеюсь, вы уже знаете, как это сделать: добавьте следующий код в конец index.jsфайла:

/* MONGOOSE SETUP */

const mongoose = require ('mongoose’) ;

const passportLocalMongoose = require ('passport-local-mongoose’) ;

mongoose.connect ('mongodb: //localhost/MyDatabase’,

{ useNewUrlParser: true, useUnifiedTopology: true }) ;

const Schema = mongoose.Schema;

const UserDetail = new Schema ({

username: String,

password: String

}) ;

UserDetail.plugin (passportLocalMongoose) ;

const UserDetails = mongoose.model ('userInfo’, UserDetail, 'userInfo’) ;

Здесь нам потребуются ранее установленные пакеты. Затем мы подключаемся к нашей базе данных с помощью mongoose.connectи указываем путь к нашей базе данных. Далее мы используем схему для определения нашей структуры данных. В этом случае мы создаем UserDetailсхему с полями usernameи.password

Наконец, мы добавляем passportLocalMongooseплагин в нашу схему. Это сработает часть магии, о которой мы говорили ранее. Затем мы создаем модель из этой схемы. Первый параметр — это имя коллекции в базе данных. Второй — ссылка на нашу схему, а третий — имя, которое мы присваиваем коллекции внутри Mongoose.

Это все, что касается настройки Mongoose. Теперь мы можем перейти к реализации нашей стратегии Passport.

Внедрение локальной аутентификации

И, наконец, это то, ради чего мы сюда пришли! Настроим локальную аутентификацию. Как вы увидите ниже, мы просто напишем код, который настроит его за нас:

/* PASSPORT LOCAL AUTHENTICATION */

passport.use (UserDetails.createStrategy ());

passport.serializeUser (UserDetails.serializeUser ());

passport.deserializeUser (UserDetails.deserializeUser ());

Здесь происходит какое-то волшебство. Во- первых, мы passportиспользуем локальную стратегию, вызывая createStrategy () нашу UserDetailsмодель — любезно предоставленную passport-local-mongoose— которая позаботится обо всем, поэтому нам не нужно настраивать стратегию. Довольно удобно.

Затем мы используем serializeUserи deserializeUserобратные вызовы. Первый будет вызываться при аутентификации, и его задача состоит в сериализации экземпляра пользователя с информацией, которую мы ему передаем, и сохранении ее в сеансе через файл cookie. Второй будет вызываться при каждом последующем запросе на десериализацию экземпляра, предоставляя ему уникальный идентификатор файла cookie в качестве «учетных данных». Подробнее об этом можно прочитать в документации Passport.

Маршруты

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

npm install connect-ensure-login

Пакет connect-ensure-login — это промежуточное программное обеспечение, которое обеспечивает вход пользователя в систему. Если получен запрос, не прошедший проверку подлинности, запрос будет перенаправлен на страницу входа. Мы будем использовать это для охраны наших маршрутов.

Теперь добавьте следующее внизу index.js:

/* ROUTES */

const connectEnsureLogin = require ('connect-ensure-login’) ;

app.post ('/login’, (req, res, next) => {

passport.authenticate ('local’,

(err, user, info) => {

if (err) {

return next (err) ;

}

if (! user) {

return res.redirect ('/login? info=' + info) ;

}

req.logIn (user, function (err) {

if (err) {

return next (err) ;

}

return res.redirect ('/') ;

}) ;

}) (req, res, next) ;

}) ;

app.get ('/login’,

(req, res) => res.sendFile ('html/login.html’,

{ root: __dirname })

) ;

app.get ('/',

connectEnsureLogin.ensureLoggedIn (),

(req, res) => res.sendFile ('html/index.html’, {root: __dirname})

) ;

app.get ('/private’,

connectEnsureLogin.ensureLoggedIn (),

(req, res) => res.sendFile ('html/private.html’, {root: __dirname})

) ;

app.get ('/user’,

connectEnsureLogin.ensureLoggedIn (),

(req, res) => res.send ({user: req.user})

) ;

Вверху мы требуем connect-ensure-login. Мы вернемся к этому позже.

Затем мы настраиваем маршрут для обработки POST-запроса к /loginпути. Внутри обработчика мы используем методpassport.authenticate, который пытается аутентифицироваться с помощью стратегии, которую он получает в качестве своего первого параметра — в данном случае local. Если аутентификация не удалась, он перенаправит нас на /login, но добавит параметр запроса — info— который будет содержать сообщение об ошибке. В противном случае, если аутентификация прошла успешно, он перенаправит нас на '/'маршрут.

Затем настраиваем /loginмаршрут, по которому будет отправляться страница входа. Для этого мы используем res.sendFile () и передаем путь к файлу и наш корневой каталог, над которым мы работаем — отсюда и расширение __dirname.

Маршрут /loginбудет доступен всем, а наши следующие — нет. В маршрутах /и /private​​мы будем отправлять соответствующие HTML-страницы, и здесь вы заметите кое-что другое. Перед обратным вызовом мы добавляем connectEnsureLogin.ensureLoggedIn () call. Это наш охранник маршрута. Его работа заключается в проверке сеанса, чтобы убедиться, что вам разрешено просматривать этот маршрут. Теперь вы понимаете, что я имел в виду ранее, говоря «позволить серверу делать всю тяжелую работу»? Мы аутентифицируем пользователя каждый раз.

Наконец, нам понадобится /userмаршрут, который будет возвращать объект с информацией о пользователе. Это просто для того, чтобы показать вам, как вы можете получать информацию с сервера. Мы запросим этот маршрут у клиента и отобразим результат.

Говоря о клиенте, давайте сделаем это сейчас.

Клиент

Клиент должен быть достаточно простым. Мы создадим несколько HTMLстраниц и CSSфайл. Начнем с домашней страницы, или index. В корне вашего проекта создайте папку с именем htmlи добавьте файл с именем index.html. Добавьте к нему следующее:

<! DOCTYPE html>

 

 

 

 

 

 

 

 

 

 

 

 

Go to private area

 

 

 

 

Здесь у нас есть пустой h1тег, куда мы поместим приветственное сообщение, а под ним ссылку на /private. Важнейшей частью здесь является scriptтег внизу, где мы будем обрабатывать получение имени пользователя для создания приветственного сообщения.

Он разделен на четыре части:

Мы создаем экземпляр объекта запроса, используя new XMLHttpRequest ().

Мы устанавливаем onreadystatechangeсвойство с функцией, которая будет вызываться после того, как мы получим наш ответ. В обратном вызове мы проверяем, получили ли мы успешный ответ, и если да, мы анализируем ответ, получаем пользовательский объект (тот, который мы отправили в /userмаршруте, помните?), и мы находим welcome-messageэлемент, чтобы установить его innerTextв наш user.username.

Мы делаем open () запрос GETпользователю URLи устанавливаем последний параметр, trueчтобы сделать его asynchronous.

Наконец, мы send () запрос.

Теперь мы создадим страницу входа. Как и прежде, в папке HTML создайте файл с именем login.htmlи добавьте в него следующее содержимое:

<! DOCTYPE html>

 

 

 

 

 

 

 

 

 

 

 

Login

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

На этой странице у нас есть простая форма входа с полями usernameи password, а также кнопка «Отправить «. Ниже у нас есть метка, где мы будем отображать любые сообщения об ошибках. Помните, что они содержатся в строке запроса.

На scriptэтот раз тег внизу намного проще. Мы создаем экземпляр URLSearchParamsобъекта, передающего window.location.searchсвойство, которое содержит строку параметров в нашем URL-адресе. Затем мы используем URLSearchParams.get () метод, передавая имя параметра, который мы ищем.

На данный момент у нас либо есть информационное сообщение, либо нет. Поэтому, если мы это сделаем, мы получим error-messageэлемент и установим его innerTextв любое сообщение, а затем установим его style.displayсвойство в block. Это сделает его видимым, учитывая, что по умолчанию он имеет display: «none»значение.

Теперь настроим личную страницу. Снова создайте файл в папке HTML с именем private.htmlи добавьте следующее содержимое:

<! DOCTYPE html>

 

 

 

 

 

 

 

 

 

This is a private area

Only you can see it

Go back

 

 

 

 

Супер просто. Простое сообщение и Go backссылка, которая возвращает нас на главную страницу.

Вот и все для HTML, но, как вы, наверное, заметили, мы ссылаемся на CSSфайл headтегов. Давайте добавим этот файл сейчас. Создайте папку с именем cssв корне нашего проекта и добавьте styles.cssв нее файл со следующим содержимым:

body {

display: flex;

align-items: center;

background: #37474F;

font-family: monospace;

color: #cfd8dc;

justify-content: center;

font-size: 20px;

}

.message-box {

text-align: center;

}

a {

color: azure;

}

.field {

margin: 10px;

}

input {

font-family: monospace;

font-size: 20px;

border: none;

background: #1c232636;

color: #CFD8DC;

padding: 7px;

border: #4c5a61 solid 2px;

width: 300px;

}

.submit-btn {

width: 100%

}

.title {

margin: 10px 0px 20px 10px

}

#error-message {

color: #E91E63;

display: block;

margin: 10px;

font-size: large;

max-width: fit-content;

}

Это позволит нашим страницам выглядеть достаточно прилично. Давайте проверим это!

Возьмите терминал, указывающий на корень проекта, и выполните следующую команду:

node index.js

Теперь перейдите по адресу http: //localhost:3000/ в браузере. Вы должны быть перенаправлены на страницу входа. Если вы попытаетесь перейти на http: //localhost:3000/private, он должен снова перенаправить вас на страницу входа. Там наша охрана маршрута делает свою работу.

Нажмите Ctrl+ Cв окне терминала, чтобы остановить наш сервер. Затем вернитесь к index.jsфайлу и в нижней части файла добавьте следующие строки:

/* REGISTER SOME USERS */

UserDetails.register ({username:'paul’, active: false}, 'paul’) ;

UserDetails.register ({username:'jay’, active: false}, 'jay’) ;

UserDetails.register ({username:'roy’, active: false}, 'roy’) ;

Это использует метод паспорта-местного-мангуста register, чтобы солить пароль для нас. Нам просто нужно передать его в виде простого текста.

Теперь бежим node index.js. Пользователи будут созданы. Вы должны прокомментировать эти последние строки сейчас.

Помните терминал оболочки MongoDB, который мы оставили открытым? Вернитесь к нему и введите:

db.userInfo.find ()

Это должно показать ваших трех пользователей, и, как вы можете видеть, соль и хэш теперь занимают значительную часть места на терминале.

Это все, что нам нужно для работы приложения. Были сделаны!

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

Следующие шаги

Мы только добавили необходимые модули для работы этого приложения — ни больше, ни меньше. Для производственного приложения вам потребуется добавить другое промежуточное ПО и разделить код на модули. Вы можете принять это как вызов, чтобы настроить чистую и масштабируемую среду и превратить ее во что-то полезное!

Первое и самое простое, что вы должны попробовать, это добавить logout, используя метод req.logout () в Passport.

Затем вы можете попробовать реализовать поток регистрации. Вам понадобится регистрационная форма и маршрут для разговора. Вы должны использовать UserDetails.register () добавленный ранее в качестве шаблона. Для подтверждения по электронной почте вы должны проверить nodemailer.

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

Вывод

Ну вот мы и подошли к концу. В этой статье мы узнали, как реализовать локальную аутентификацию с Passportпомощью Node.jsприложения. В процессе мы также узнали, как подключиться с MongoDBпомощью Mongoose.

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

«Волшебные» инструменты не всегда идеальны, но надежные и активно поддерживаемые инструменты помогают нам писать меньше кода, а код, который вы не пишете, — это код, который вы не поддерживаете, а код, который вы не поддерживаете, — это код, который вы не ломаете...

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

Надеюсь, вам понравился этот урок, и, возможно, вы получили вдохновение для своего следующего проекта. Удачного кодирования!

3D-печать5GABC-анализAndroidAppleAppStoreAsusCall-центрChatGPTCRMDellDNSDrupalExcelFacebookFMCGGoogleHuaweiInstagramiPhoneLinkedInLinuxMagentoMicrosoftNvidiaOpenCartPlayStationPOS материалPPC-специалистRuTubeSamsungSEO-услугиSMMSnapchatSonyStarlinkTikTokTwitterUbuntuUp-saleViasatVPNWhatsAppWindowsWordPressXiaomiYouTubeZoomАвдеевкаАктивные продажиАкцияАлександровск ЛНРАлмазнаяАлчевскАмвросиевкаАнализ конкурентовАнализ продажАнтимерчандайзингАнтрацитАртемовскАртемовск ЛНРАссортиментная политикаБелгородБелицкоеБелозерскоеБердянскБизнес-идеи (стартапы)БрендБрянкаБукингВахрушевоВендорВидеоВикипедияВирусная рекламаВирусный маркетингВладивостокВнутренние продажиВнутренний маркетингВолгоградВолновахаВоронежГорловкаГорнякГорскоеДебальцевоДебиторкаДебиторская задолженностьДезинтермедитацияДзержинскДивизионная система управленияДизайнДимитровДирект-маркетингДисконтДистрибьюторДистрибьюцияДобропольеДокучаевскДоменДружковкаЕкатеринбургЕнакиевоЖдановкаЗапорожьеЗимогорьеЗолотоеЗоринскЗугрэсИжевскИловайскИрминоКазаньКалининградКировскКировскоеКомсомольскоеКонстантиновкаКонтент-маркетингКонтент-планКопирайтингКраматорскКрасноармейскКрасногоровкаКраснодарКраснодонКраснопартизанскКрасный ЛиманКрасный ЛучКременнаяКураховоКурскЛисичанскЛуганскЛутугиноМакеевкаМариупольМаркетингМаркетинговая информацияМаркетинговые исследованияМаркетинговый каналМаркетинг услугМаркетологМарьинкаМедиаМелекиноМелитопольМенеджментМерчандайзерМерчандайзингМиусинскМолодогвардейскМоскваМоспиноНижний НовгородНиколаевНиколаевкаНишевой маркетингНовоазовскНовогродовкаНоводружескНовосибирскНумерическая дистрибьюцияОдессаОмскОтдел маркетингаПартизанский маркетингПервомайскПеревальскПетровскоеПлата за кликПоисковая оптимизацияПопаснаяПравило ПаретоПривольеПрогнозирование продажПродвижение сайтов в ДонецкеПроизводство видеоПромоПромоушнПрямой маркетингРабота для маркетологаРабота для студентаРазработка приложенийРаспродажаРегиональные продажиРекламаРеклама на асфальтеРемаркетингРетро-бонусРибейтРитейлРовенькиРодинскоеРостов-на-ДонуРубежноеСамараСанкт-ПетербургСаратовСватовоСвердловскСветлодарскСвятогорскСевастопольСеверодонецкСеверскСедовоСейлз промоушнСелидовоСимферопольСинергияСколковоСлавянскСнежноеСоздание сайтов в ДонецкеСоледарСоциальные сетиСочиСтаробельскСтаробешевоСтахановСтимулирование сбытаСуходольскСчастьеТелемаркетингТельмановоТираспольТорговый представительТорезТрейд маркетингТрейд промоушнТюменьУглегорскУгледарУкраинскХабаровскХарцызскХерсонХостингЦелевая аудиторияЦифровой маркетингЧасов ЯрЧелябинскШахтерскЮжно-СахалинскЮнокоммунаровскЯндексЯсиноватая