Общим требованием при создании
В этом руководстве я покажу, как использовать 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
Прежде чем мы начнем, давайте кратко поговорим о вариантах аутентификации.
Многие современные
Аутентификация на основе сеанса существует дольше. Этот метод передает вес аутентификации серверу. Он использует файлы cookie и видит, как приложение Node и база данных работают вместе, чтобы отслеживать состояние аутентификации пользователя.
В этом руководстве мы будем использовать аутентификацию на основе сеанса, которая лежит в основе стратегии «
Оба метода имеют свои преимущества и недостатки. Если вы хотите узнать больше о разнице между ними, эта ветка Stack Overflow может быть хорошим местом для начала.
Создание проекта
После установки всего необходимого программного обеспечения можно приступать к работе.
Мы начнем с создания папки для нашего приложения, а затем получим доступ к этой папке на терминале:
mkdir AuthApp
cd AuthApp
Чтобы создать приложение узла, мы будем использовать следующую команду:
npm init
Вам будет предложено предоставить некоторую информацию для Node package.json. Просто продолжайте нажимать Return, чтобы принять конфигурацию по умолчанию (или используйте -yфлаг).
Настройка Экспресс
Теперь нам нужно установить Express. Перейдите в терминал и введите эту команду:
npm install express
Нам также потребуется установить промежуточное ПО
Давайте сделаем это. Выполните следующую команду:
npm install
Когда это будет сделано, создайте index.jsфайл в корневой папке вашего приложения и добавьте в него следующее содержимое:
/* EXPRESS SETUP */
const express = require ('express’) ;
const app = express () ;
app.use (express.static (__dirname));
const bodyParser = require ('
const expressSession = require ('
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промежуточное ПО
Как видите, мы настраиваем
Затем мы используем process.env.PORTдля установки порта переменную порта среды, если она существует. В противном случае по умолчанию 3000будет использоваться порт, который мы будем использовать локально. Это дает вам достаточную гибкость, чтобы переключиться с разработки непосредственно на производственную среду, где порт может быть установлен поставщиком услуг, таким как, например, Heroku. Прямо под этим мы вызвали app.listen () с настроенной нами переменной порта и простым журналом, чтобы мы знали, что все работает нормально и какой порт прослушивает приложение.
Это все, что касается
Настройка паспорта
Сначала мы устанавливаем 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 -
Давайте установим пакет:
npm install
Теперь нам нужно настроить Mongoose. Надеюсь, вы уже знаете, как это сделать: добавьте следующий код в конец index.jsфайла:
/* MONGOOSE SETUP */
const mongoose = require ('mongoose’) ;
const passportLocalMongoose = require ('
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 ());
Здесь происходит
Затем мы используем serializeUserи deserializeUserобратные вызовы. Первый будет вызываться при аутентификации, и его задача состоит в сериализации экземпляра пользователя с информацией, которую мы ему передаем, и сохранении ее в сеансе через файл cookie. Второй будет вызываться при каждом последующем запросе на десериализацию экземпляра, предоставляя ему уникальный идентификатор файла cookie в качестве «учетных данных». Подробнее об этом можно прочитать в документации Passport.
Маршруты
Теперь давайте добавим несколько маршрутов, чтобы связать все вместе.
npm install
Пакет
Теперь добавьте следующее внизу index.js:
/* ROUTES */
const connectEnsureLogin = require ('
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})
) ;
Вверху мы требуем
Затем мы настраиваем маршрут для обработки
Затем настраиваем /loginмаршрут, по которому будет отправляться страница входа. Для этого мы используем res.sendFile () и передаем путь к файлу и наш корневой каталог, над которым мы работаем — отсюда и расширение __dirname.
Маршрут /loginбудет доступен всем, а наши следующие — нет. В маршрутах /и /privateмы будем отправлять соответствующие
Наконец, нам понадобится /userмаршрут, который будет возвращать объект с информацией о пользователе. Это просто для того, чтобы показать вам, как вы можете получать информацию с сервера. Мы запросим этот маршрут у клиента и отобразим результат.
Говоря о клиенте, давайте сделаем это сейчас.
Клиент
Клиент должен быть достаточно простым. Мы создадим несколько HTMLстраниц и CSSфайл. Начнем с домашней страницы, или index. В корне вашего проекта создайте папку с именем htmlи добавьте файл с именем index.html. Добавьте к нему следующее:
<! DOCTYPE html>
Здесь у нас есть пустой h1тег, куда мы поместим приветственное сообщение, а под ним ссылку на /private. Важнейшей частью здесь является scriptтег внизу, где мы будем обрабатывать получение имени пользователя для создания приветственного сообщения.
Он разделен на четыре части:
Мы создаем экземпляр объекта запроса, используя new XMLHttpRequest ().
Мы устанавливаем onreadystatechangeсвойство с функцией, которая будет вызываться после того, как мы получим наш ответ. В обратном вызове мы проверяем, получили ли мы успешный ответ, и если да, мы анализируем ответ, получаем пользовательский объект (тот, который мы отправили в /userмаршруте, помните?), и мы находим
Мы делаем open () запрос GETпользователю URLи устанавливаем последний параметр, trueчтобы сделать его asynchronous.
Наконец, мы send () запрос.
Теперь мы создадим страницу входа. Как и прежде, в папке HTML создайте файл с именем login.htmlи добавьте в него следующее содержимое:
<! DOCTYPE html>
На этой странице у нас есть простая форма входа с полями usernameи password, а также кнопка «Отправить «. Ниже у нас есть метка, где мы будем отображать любые сообщения об ошибках. Помните, что они содержатся в строке запроса.
На scriptэтот раз тег внизу намного проще. Мы создаем экземпляр URLSearchParamsобъекта, передающего window.location.searchсвойство, которое содержит строку параметров в нашем
На данный момент у нас либо есть информационное сообщение, либо нет. Поэтому, если мы это сделаем, мы получим
Теперь настроим личную страницу. Снова создайте файл в папке HTML с именем private.htmlи добавьте следующее содержимое:
<! DOCTYPE html>
Супер просто. Простое сообщение и Go backссылка, которая возвращает нас на главную страницу.
Вот и все для HTML, но, как вы, наверное, заметили, мы ссылаемся на CSSфайл headтегов. Давайте добавим этот файл сейчас. Создайте папку с именем cssв корне нашего проекта и добавьте styles.cssв нее файл со следующим содержимым:
body {
display: flex;
background: #37474F;
color: #cfd8dc;
}
.
}
a {
color: azure;
}
.field {
margin: 10px;
}
input {
border: none;
background: #1c232636;
color: #CFD8DC;
padding: 7px;
border: #4c5a61 solid 2px;
width: 300px;
}
.
width: 100%
}
.title {
margin: 10px 0px 20px 10px
}
#
color: #E91E63;
display: block;
margin: 10px;
}
Это позволит нашим страницам выглядеть достаточно прилично. Давайте проверим это!
Возьмите терминал, указывающий на корень проекта, и выполните следующую команду:
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’) ;
Это использует метод
Теперь бежим node index.js. Пользователи будут созданы. Вы должны прокомментировать эти последние строки сейчас.
Помните терминал оболочки MongoDB, который мы оставили открытым? Вернитесь к нему и введите:
db.userInfo.find ()
Это должно показать ваших трех пользователей, и, как вы можете видеть, соль и хэш теперь занимают значительную часть места на терминале.
Это все, что нам нужно для работы приложения. Были сделаны!
Вернитесь в браузер, попробуйте войти в систему с одним из введенных нами учетных данных, и вы увидите сообщение о входе с указанным именем пользователя.
Следующие шаги
Мы только добавили необходимые модули для работы этого приложения — ни больше, ни меньше. Для производственного приложения вам потребуется добавить другое промежуточное ПО и разделить код на модули. Вы можете принять это как вызов, чтобы настроить чистую и масштабируемую среду и превратить ее во
Первое и самое простое, что вы должны попробовать, это добавить logout, используя метод req.logout () в Passport.
Затем вы можете попробовать реализовать поток регистрации. Вам понадобится регистрационная форма и маршрут для разговора. Вы должны использовать UserDetails.register () добавленный ранее в качестве шаблона. Для подтверждения по электронной почте вы должны проверить nodemailer.
Вы также можете попробовать применить эти концепции к одностраничному приложению. Возможно, используя Vue.js и его роутер. Вот и прошли ваши выходные!
Вывод
Ну вот мы и подошли к концу. В этой статье мы узнали, как реализовать локальную аутентификацию с Passportпомощью Node.jsприложения. В процессе мы также узнали, как подключиться с MongoDBпомощью Mongoose.
Возможно, это было не так просто для вас, как я пытался это нарисовать, но, по крайней мере, вы должны увидеть, что это становится проще с этими инструментами, которые творят магию в фоновом режиме, позволяя нам беспокоиться только о том, что мы пытаемся построить...
«Волшебные» инструменты не всегда идеальны, но надежные и активно поддерживаемые инструменты помогают нам писать меньше кода, а код, который вы не пишете, — это код, который вы не поддерживаете, а код, который вы не поддерживаете, — это код, который вы не ломаете...
Кроме того, имейте в виду, что если инструмент активно поддерживается основной командой, скорее всего, они знают, что делают лучше, чем
Надеюсь, вам понравился этот урок, и, возможно, вы получили вдохновение для своего следующего проекта. Удачного кодирования!