1. Главная страница » Компьютеры » Node js express авторизация

Node js express авторизация

Автор: | 16.12.2019

Реализация надежных систем аутентификации для любого приложения может стать непростой задачей, приложение Node.js здесь не исключение.

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

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

Это позволяет Passport легко настроить любое веб-приложение на базе Express , так же, как мы можем просто настроить другой связующий Express -софт, например, logging , body-parsing , cookie-parsing , session-handling и т.д.

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

Стратегии аутентификации

Passport предлагает нам на выбор свыше 140 механизмов аутентификации. Вы можете проводить аутентификацию с помощью локального/удаленного экземпляра объекта базы данных или использовать единый вход с использованием OAuth , предоставляемый Facebook , Twitter , Google и т.д., для аутентификации в ваших аккаунтах социальных медиа.

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

Но не беспокоитесь: Вам не нужно включать все стратегии / механизмы , которые вашему приложению и не нужны. Все эти стратегии являются независимыми друг от друга и упакованы в виде отдельных модулей узлов, которые не включаются по умолчанию при установке связующего программного обеспечения Passport : npm install passport .

В этой статье мы будем использовать локальную стратегию аутентификации Passport и аутентификацию пользователей с помощью локально настроенного экземпляра объекта Монго DB , хранящего информацию о пользователе в базе данных.

Для использования стратегии локальной аутентификации, мы должны установить модуль passport-local : npm install passport-local .

Но подождите минутку: перед тем, как вы запустите терминал и начнете выполнение этих команд, давайте все же рассмотрим построение приложения Express с нуля и добавление к нему некоторых маршрутов ( для авторизации, регистрации и главной страницы ), а затем добавим связующий софт для аутентификации.

Обратите внимание, что в этой статье мы будем использовать Express 4 , но с некоторыми незначительными отличиями Passport одинаково хорошо работает с Express 3 .

Настройка приложения

Если вы еще этого не сделали, то установите Express и express-generator для создания шаблонных приложений. Для этого нужно просто выполнить в терминале команду express passport-mongo . Сформированная структура приложения должна выглядеть следующим образом:


Давайте удалим некоторый функционал по умолчанию, который нам вовсе необязательно использовать — удалите маршрут users.js и уберите все его ссылки из файла app.js .

Добавление зависимостей проекта

Откройте файл package.json и добавьте в него зависимости для passport и модуля passport-local :

Так как мы будем сохранять информацию о пользователе в MongoDB , мы будем использовать Mongoose в качестве инструмента моделирования данных объекта. Также установить и сохранить зависимость для package.json можно с помощью команды:

package.json должен выглядеть следующим образом:


Теперь установите все зависимости и запустите шаблонное приложение, выполнив команду npm install && npm start . Она загружает и устанавливает все зависимости и запускает сервер узла. Вы можете проверить установку приложения Express , перейдя по адресу: http://localhost:3000/ , но там вы пока еще ничего особенного не увидите.

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

Читайте также:  Canon 50d ресурс затвора

Создание модели Mongoose

Так как мы будем сохранять информацию о пользователях в Mongo , давайте создадим модель пользователя в Mongoose и сохраним ее в файле models/user.js нашего приложения:

Мы создаем модель Mongoose , с помощью которой мы можем выполнять CRUD операции в основной базе данных.

Конфигурация Mongo

Если у вас нет установленного локально Mongo , мы рекомендуем использовать облачные сервисы баз данных, такие как Modulus или MongoLab .

Создание рабочего экземпляра MongoDB с их помощью не только бесплатно, но кроме того это можно сделать всего лишь в несколько кликов.

После создания базы данных на одном из этих сервисов, вы получите URI базы данных, наподобие mongodb://:@novus.modulusmongo.net:27017/ , который можно использовать для выполнения CRUD -операций с базой данных.

Я рекомендую сохранить конфигурацию базы данных в отдельный файл, который можно будет подтянуть, когда это будет необходимо. Таким образом, мы создаем модуль узла db.js , который выглядит следующим образом:

Теперь мы используем эту конфигурацию в app.js и подключаемся к ней с помощью Mongoose API :

Конфигурация Passport

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

Откройте файл app.js и вставьте перед настройкой маршрутов приведенный ниже код:

Это необходимо, поскольку мы хотим, чтобы сеансы пользователей были стабильными. Перед запуском приложения мы должны установить express-session и добавить его в список зависимостей файла package.json . Для этого наберите в командной строке — npm install —save express-session .

Сериализация и десериализация экземпляров объекта пользователя

Для Passport также необходима сериализация и десериализация экземпляра объекта пользователя из сессии сохранения в целях поддержки текущей сессии, так чтобы каждый последующий запрос не содержал учетные данные пользователя. Для этого предназначены два метода serializeUser и deserializeUser :

Использование стратегий Passport

Теперь мы определим стратегии Passport для обработки авторизации и регистрации. Каждая из них будет экземпляром стратегии локальной аутентификации Passport и будет создаваться при помощи функции passport.use() .

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

Стратегия авторизации

Стратегия авторизации выглядит следующим образом:

Первый параметр passport.use() является именем стратегии, которое будет использоваться для идентификации этой стратегии при последующем применении. Вторым параметром является тип стратегии, которую вы хотите создать, здесь мы используем username-password или LocalStrategy .

Следует отметить, что по умолчанию LocalStrategy ищет учетные данные пользователя в параметрах username и password , но мы можем также использовать любые другие проименованные параметры.

Переменная конфигурации passReqToCallback позволяет нам получить доступ к объекту request в функции обратного вызова, благодаря чему, в свою очередь, мы имеем возможность использовать любой параметр, связанный с запросом.

Далее, мы используем Mongoose API , чтобы найти пользователя в нашей основной базе пользователей и проверить, является ли он доверенным пользователем или нет.

Последний параметр в нашем обратном вызове done указывает на используемый метод, с помощью которого мы сообщаем модулю Passport об успешном выполнении действия или ошибке.

Чтобы идентифицировать сбой либо первый параметр должен содержать ошибку, либо второй параметр должен содержать значение false . Для обозначения успешного прохождения действия первый параметр должен иметь значение null , а второй — truthy , в этом случае объект request становится доступен.

Поскольку пароли по своей природе являются уязвимым местом, мы всегда должны шифровать их перед сохранением в базу данных. Для этого мы используем bcrypt-nodejs , который помогает шифровать и расшифровывать пароли:

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

Стратегия регистрации

Теперь мы определяем следующую стратегию, которая будет обрабатывать регистрацию нового пользователя и создавать его учетную запись в основной базе данных Mongo DB :

Здесь мы снова использовали Mongoose API , чтобы выяснить, существует ли пользователь с данным именем пользователя или нет. Если нет, то создаем нового пользователя и сохраняем информацию о нем в Mongo .

Читайте также:  Angry birds не запускается

В противном случае возвращаем ошибку с помощью обратного вызова done и флэш-сообщения. Обратите внимание, что мы используем bcrypt-nodejs для создания хэша пароля перед его сохранением:

Создание маршрутов

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


Теперь мы задаем маршруты для применения в следующем модуле, который принимает экземпляр паспорта созданного ранее в app.js . Сохраните этот модуль в файле routes/index.js :

Наиболее важной частью приведенного выше фрагмента кода является использование passport.authenticate() для делегирования аутентификации стратегиям login и signup , когда HTTP POST выполнен для маршрутов /login и /signup соответственно.

Обратите внимание, что не обязательно называть стратегии соответственно пути маршрута, им можно назначать произвольные имена.

Создание представлений Jade

Далее, мы создаем следующие два представления для нашего приложения:

  • layout.jade — содержит базовую структуру и информацию о стилях;
  • index.jade — содержит страницу авторизации, включающую форму входа и опции для создания новой учетной записи:

Благодаря Bootstrap наша страница авторизации теперь выглядит следующим образом:


Нам также потребуются еще два представления для ввода регистрационных данных и для домашней страницы приложения:

  • register.jade — содержит форму регистрации;
  • home.jade — выводит приветствие и данные авторизовавшегося пользователя.

Если вы не работали с Jade , здесь можете найти документацию по нему.

Реализация функции выхода из системы

Passport , будучи связующим софтом, позволяет добавлять определенные свойства и методы к объектам запросов и ответов, что в свою очередь дает возможность добавить очень удобный метод request.logout() , который отменяет сеанс пользователя:

Защита маршрутов

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

Это означает, что если некоторые пользователи пытается получить доступ к маршруту http://localhost:3000/home без авторизации в системе, они будут перенаправлены на главную страницу следующим образом:

Заключение

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

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

Я начал изучать Node.js и начал делать авторизацию пользователей, но попал в тупик. Вот что я хочу реализовать:
— пользователь входит в систему
— перенаправляет его на страницу пользователя
— данные об отпуске пользователя отображаются на странице пользователя
Но я застрял на последнем пункте. Как я могу передать req.session.user в запрос get или есть другой способ? Вот мой код:
index.js

  • Вопрос задан 17 авг.
  • 143 просмотра

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

Добро пожаловать в пятую часть руководства по созданию веб-приложения с помощью Node.js. В рамках серии уроков будет рассказано про основные особенности и трудности, которые возникают при работе с Node.js.

5.1. Аутентификация¶

Мы уже сделали достаточно полезное приложение. Но оно было бы еще более полезным, если бы имело какое-либо подобие системы аутентификации. Даже не смотря на то, что в миру набирают обороты такие технологии, как OpenID и OAuth, большинство коммерческих проектов предпочитают иметь свою собственную систему входа.

Обычно она реализуется с помощью сессий:

  • Пользователь заполняет форму, указывая логин и пароль
  • Пароль шифруется с помощью хэш-алгоритма
  • Полученное значение сравнивается с тем, что хранится в БД
  • Если они совпадают, то генерируется сессионный ключ, идентифицирующий пользователя

Для реализации пользовательских сессий нам нужно следующее:

  • Пользователь в БД
  • Сессии, в которых можно хранить идентификатор пользователя
  • Шифрование пароля
  • Возможность ограничения доступа к тем URL, для которых требуется залогиненный пользователь

5.2. Сессии в Express¶

В основе сессий в Express лежит соответствующий средний слой (middleware) из Connect, который, в свою очередь, опирается на механизм хранения данных. Существует хранилище в памяти, а так же сторонние хранилища, включая connect-redis и connect-mongodb. В качестве альтернативы так же можно рассматривать cookie-sessions, который хранит данные сессии в пользовательской куке (cookie).

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

Читайте также:  Monkrus официальный сайт windows 10

Размещение этого кода в разделе конфигурации приложения очень важно. В случае ошибки сессионная переменная не появится в объекте запроса. Я разместил этот кусок между bodyDecoder и methodOverride . Полную версию кода вы можете посмотреть на GitHub.

Теперь в HTTP-обработчиках будет доступна переменная req.session :

5.3. Сессии в MongoDB¶

Для поддержки сессий в MongoDB необходимо установить connect-mongodb:

Работает connect-mongodb так же как и любое другое хранилище сессий. Во время настройки приложения необходимо указать детали соединения:

Большая часть этого кода не понадобилась бы, если бы авторы API реализовали стандартный формат настроек соединения. Я написал функцию, извлекающую настройки соединения из Mongoose. В этом примере, переменная db хранит экземпляр соединения Mongoose, который ждет настроек соединения в виде URI. Этот формат, кстати, мне более всего симпатичен из-за своей простоты и легкости для запоминания. Строку соединения я сохраняю с помощью app.set .

При работе с Express бывает полезно использовать app.set(‘name’, ‘value’) . Так же следует запомнить, что для доступа к настройке следует использовать app.set(‘name’) , а не app.get .

Теперь, запустив в консоли Mongo db.sessions.find() , можно увидеть все созданные сессии.

5.4. Контроль доступа¶

Express предоставляет элегатный способ по ограничению доступа для залогиненных пользователей. При определения HTTP-обработчика может быть задан необязательный параметр маршрутизации:

Теперь доступ к адресу (URL), требующему только авторизованных пользователей, может быть ограничен простым добавлением loadUser в соответствующий HTTP-обработчик. Вспомогательная функция принимает те же параметры, что и обычный обработчик, плюс один дополнительный параметр next . Последний позволяет использовать дополнительную логику перед непосредственным вызовом функции обработчика адреса. В нашем проекте, пользователь загружается, используя сессионую переменную user_id . Если пользователь не найден, то функция next не вызывается и происход переадресация на окно ввода логина/пароля.

5.5. RESTful подход к сессиям¶

Я сделал сессии таким же образом, как и документы. Добавил адреса для создания, удаления и получения сессий:

5.6. Модель пользователя¶

Модель пользователя User немного сложнее, чем модель документа Document , так как в ней будет содержаться код связанный с авторизацией. Я использовал следующую стратегию, которую, вероятно, вы уже видели ранее в объектно-ориентированных веб фреймворках:

  • Пароли хранятся в виде хэша
  • Аутентификация выполняется сравнением зашифрованного текста, указанного пользователем, и паролем-хэшем, хранящимся в БД для пользователя
  • Виртуальное свойство password хранит пароль в текстовом виде для удобства в формах регистрации и входа
  • У свойства есть сеттер, который автоматически конвертирует текст пароля в хэш перед сохранением
  • Используется уникальный индекс для поля email, чтобы гарантировать, что у каждого пользователя свой собственный email

Шифрование пароля использует стандартную Node.js библиотеку crypto :

encryptPassword — метод экземпляра, возвращающий sha1-хэш для текстового пароля и некоторой соли. Соль генерируется перед шифрованием в сеттере пароля:

Солью может быть всё, что угодно. Я, в данном примере, генерирую случайную строку.

5.7. Сохранение пользователей и регистрация¶

Mongoose позволяет изменять поведение модели при сохранении с помощью переопределения метода save :

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

Пока не выводится никаких сообщений об ошибках. Это будет добавлено в одной из следующих частей.

Несмотря на всю простоту этой проверки, индекс критически важен для приложения:

Эта проверка предотвратит дублирование пользователей при сохранении.

5.8. Заключение¶

После коммита 03fe9b2 мы имеем следующее:

  • Сессии в MongoDB
  • Модель пользователя с поддержкой шифрования пароля алгоритмом sha-1
  • Контроль доступа к документам
  • Регистрацию и аутентифкацию пользователей
  • Управление сессиями

Я немного обновил Jade шаблоны и добавил форму входа.

Есть, однако, несколько моментов, пока не реализованных в текущей версии приложения:

  • Документы ничего не знают о своем владельце
  • Тесты работают неправильно, так как у меня появились проблемы при анализе того, как Expresso работает с сессиями

Со всем этим мы разберемся в следующих частях руководства.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

code