Как сделать авторизацию на сайте js
Перейти к содержимому

Как сделать авторизацию на сайте js

Как сделать авторизацию на сайте js

Completing the CAPTCHA proves you are a human and gives you temporary access to the web property.

What can I do to prevent this in the future?

If you are on a personal connection, like at home, you can run an anti-virus scan on your device to make sure it is not infected with malware.

If you are at an office or shared network, you can ask the network administrator to run a scan across the network looking for misconfigured or infected devices.

Another way to prevent getting this page in the future is to use Privacy Pass. You may need to download version 2.0 now from the Chrome Web Store.

Cloudflare Ray ID: 71ae18a82bfe9b69 • Your IP : 82.102.23.104 • Performance & security by Cloudflare

Обработка аутентификации в Express.js

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

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

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

Во-первых, давайте создадим новую папку с именем, скажем, simple-web-app . Используя терминал, мы перейдем к этой папке и создадим каркасный проект Node.js:

Теперь мы также можем установить Express:

Для простоты мы будем использовать серверный движок рендеринга под названием Handlebars. Этот движок будет отображать наши HTML-страницы на стороне сервера, поэтому нам не понадобятся никакие другие передовые фреймворки, такие как Angular или React.

Давайте продолжим и установим express-handlebars :

Мы также будем использовать два других промежуточных пакета Express ( body-parser и cookie-parser ) для анализа тела HTTP-запросов и анализа необходимых файлов cookie для аутентификации:

Реализация

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

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

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

Далее, давайте создадим простое приложение Express и сконфигурируем промежуточное ПО, которое мы импортировали, вместе с движком Handlebars:

По умолчанию в Handlebars расширение шаблона должно быть .handlebars . Как вы можете видеть в этом коде, мы настроили наш шаблонизатор для поддержки файлов с более коротким расширением .hbs . Теперь давайте создадим несколько файлов шаблонов:

Папка layouts внутри папки view будет держать ваш основной макет, который обеспечит базовый HTML для других шаблонов.

Давайте создадим нашу главную страницу main.hbs :

Другие шаблоны будут отображаться внутри тега <<>> . У нас есть шаблон HTML и необходимые файлы CSS и JS для Bootstrap, импортированные в этот макет.

Закончив нашу основную оболочку, давайте создадим страницу home.hbs , где пользователям будет предложено войти в систему или зарегистрироваться:

Затем давайте создадим обработчик запроса к пути root path ( / ) для визуализации шаблона home.

Давайте запустим наше приложение и перейдем к http://localhost:3000 :

Регистрация аккаунта

Информация об учетной записи собирается через страницу registration.hbs :

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

Давайте создадим дескриптор запроса для отображения шаблона регистрации при посещении пользователя http://localhost:3000/register :

Из — за соображений безопасности, хорошая практика создавать хэш пароля с сильным алгоритмом хэширования, как SHA256 . Хешируя пароли, мы гарантируем, что даже если наша база паролей может быть скомпрометирована, пароли не будут видны в текстовом формате.

Еще лучший метод, чем простое хеширование, — использовать соль, как в алгоритме bcrypt.

Когда пользователь отправляет регистрационную форму, POST запрос будет отправлен на путь /register .

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

Так как каждый перезапуск сервера будет повторно инициализировать массив, мы будем жестко кодировать пользователя для целей тестирования, которые будут инициализироваться каждый раз:

Принимаемые email , firstName , lastName , password , и confirmPassword проверяются — пароли совпадают, адрес электронной почты не зарегистрирован и т.д.

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

Теперь давайте посетим страницу /register , чтобы проверить, что она работает правильно:

Логин аккаунта

Теперь мы можем реализовать функционал входа в систему. Давайте начнем с создания страницы login.hbs :

А затем давайте создадим обработчик для этого запроса:

Эта форма будет отправлять POST запрос на /login , когда пользователь отправляет форму. Тем не менее, еще одна вещь, которую мы будем делать, это отправка токена аутентификации для входа в систему. Этот токен будет использоваться для идентификации пользователя, и каждый раз, когда он отправляет HTTP-запрос, этот токен будет отправляться с помощью cookie:

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

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

Давайте перейдем на /login :

Мы еще не совсем закончили. Нам нужно авторизовать пользователя, прочитав из cookie authToken после получения запроса. Над всеми обработчиками запросов и под cookie-parser промежуточным программным обеспечением давайте создадим наше собственное промежуточное программное обеспечение для внедрения пользователей в запросы:

Теперь мы можем использовать req.user внутри наших обработчиков запросов, чтобы проверить, аутентифицирован ли пользователь с помощью токена.

Наконец, давайте создадим обработчик запросов для отображения защищенной страницы protected.hbs :

И обработчик запроса для страницы:

Как видите, вы можете использовать, req.user чтобы проверить, аутентифицирован ли пользователь. Если этот объект пуст, пользователь не аутентифицирован.

Другой способ требовать аутентификации на маршрутах — это реализовать его в качестве промежуточного программного обеспечения, которое затем можно применить к маршрутам напрямую, как они определены в объекте app :

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

Вывод

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

Исходный код этого проекта можно найти на GitHub

Contribute to jkasun/stack-abuse-express-authentication development by creating an account on GitHub.

Аутентификация и авторизация с JWT в Express.js

В этой статье мы поговорим о том, как работают JSON Web Tokens, каковы их преимущества, их структура и как их использовать для обработки базовой аутентификации и авторизации в Express.

Вам не обязательно иметь опыт работы с веб-токенами JSON, поскольку мы будем говорить об этом с нуля.

Для раздела реализации было бы предпочтительнее, если у вас есть предыдущий опыт работы с Express , Javascript ES6 и клиентами REST.

Что такое веб-токены JSON?

Веб-токены JSON (JWT) были введены как метод безопасного обмена данными между двумя сторонами. Он был представлен со спецификацией RFC 7519 Инженерной группой Интернета (IETF).

Несмотря на то, что мы можем использовать JWT с любым типом метода связи, сегодня JWT очень популярен для обработки аутентификации и авторизации через HTTP.

Во-первых, вам нужно знать несколько характеристик HTTP.

HTTP — это протокол без сохранения состояния, что означает, что HTTP-запрос не поддерживает состояние. Сервер не знает ни о каких предыдущих запросах, отправленных тем же клиентом.

HTTP-запросы должны быть автономными. Они должны включать информацию о предыдущих запросах, сделанных пользователем, в самом запросе.

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

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

Вот схема того, как работает аутентификация на основе сеанса:

Обычно этот идентификатор сеанса отправляется пользователю в виде файла cookie. Мы уже подробно обсуждали это в нашей предыдущей статье « Обработка аутентификации в Express.js» .

С другой стороны, с JWT, когда клиент отправляет запрос аутентификации на сервер, он отправляет токен JSON обратно клиенту, который включает в себя всю информацию о пользователе с ответом.

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

Например, предположим, что после аутентификации сервер отправляет обратно клиенту объект JSON с именем пользователя и сроком действия. Итак, поскольку объект JSON доступен для чтения, любой может изменить эту информацию и отправить запрос. Проблема в том, что нет возможности подтвердить такой запрос.

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

Мы рассмотрим это более подробно позже в этой статье.

Вот схема того, как работает JWT:

Структура JWT

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

Как вы можете видеть на изображении, JWT состоит из трех частей, каждая из которых разделена точкой.

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

Первый раздел JWT — это заголовок, представляющий собой строку в кодировке Base64. Если вы расшифруете заголовок, он будет выглядеть примерно так:

Раздел заголовка содержит алгоритм хеширования, который использовался для генерации знака и типа токена.

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

Рекомендуется не включать в JWT какие-либо конфиденциальные данные, такие как пароли или личную информацию.

Обычно тело JWT выглядит примерно так, хотя это необязательно:

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

Вы также можете увидеть некоторые общие свойства, такие как eat или exp , который является сроком действия токена.

Последний раздел — это подпись токена. Это создается путем хеширования строки base64UrlEncode(header) + "." + base64UrlEncode(payload) + secret с использованием алгоритма, упомянутого в разделе заголовка.

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

Когда эта подпись отправляется обратно на сервер, она может проверить, что клиент не изменил никаких деталей в объекте.

Согласно стандартам, клиент должен отправить этот токен на сервер через HTTP-запрос в заголовке под названием Authorization с формой Bearer [JWT_TOKEN] . Таким образом, значение Authorization будет выглядеть примерно так:

Если вы хотите узнать больше о структуре токена JWT, вы можете ознакомиться с нашей подробной статьей Understanding JSON Web Tokens . Вы также можете посетить jwt.io и поиграть с их отладчиком:

Преимущество использования JWT перед традиционными методами

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

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

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

Если мы используем традиционные методы авторизации, такие как файлы cookie, нам придется совместно использовать базу данных, такую как Redis , для обмена сложной информацией между серверами или внутренними службами. Но если мы поделимся секретом между микросервисами, мы можем просто использовать JWT, и тогда для авторизации пользователей не потребуется никаких других внешних ресурсов.

Использование JWT с Express

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

Будет два типа пользователей — администраторы и участники . Администраторы смогут просматривать и добавлять новые книги, а участники

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

Для начала в вашем терминале инициализируйте пустой проект Node.js с настройками по умолчанию:

Затем давайте установим фреймворк Express:

Служба аутентификации

Затем давайте создадим файл auth.js , который будет нашей службой аутентификации:

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

Для каждого пользователя будет назначена роль admin или member привязанная к их пользовательскому объекту. Кроме того, не забудьте хешировать пароль, если вы работаете в производственной среде:

Теперь мы можем создать обработчик запроса для входа пользователя. Давайте установим модуль jsonwebtoken , который используется для генерации и проверки токенов JWT.

Также давайте установим body-parser для анализа тела JSON из HTTP-запроса:

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

Теперь мы можем создать обработчик запроса для обработки запроса входа пользователя:

Это ваш секрет для подписи токена JWT. Вы никогда не должны делиться этим секретом, иначе злоумышленник может использовать его для подделки токенов JWT для получения несанкционированного доступа к вашему сервису. Чем сложнее этот токен доступа, тем безопаснее будет ваше приложение. Поэтому попробуйте использовать для этого токена сложную случайную строку:

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

Наша служба аутентификации готова. Загрузим его, запустив:

После того, как служба аутентификации будет запущена, давайте отправим запрос POST и посмотрим, работает ли он.

Для этого я воспользуюсь клиентом отдыха Insomnia . Не стесняйтесь использовать для этого любой клиент отдыха или что-то вроде Postman .

Давайте отправим почтовый запрос в http://localhost:3000/login со следующим JSON:

В качестве ответа вы должны получить токен доступа:

Книжная служба

После этого давайте создадим books.js для нашего книжного сервиса.

Мы начнем с файла, импортировав необходимые библиотеки и настроив приложение Express:

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

Теперь мы можем создать очень простой обработчик запросов для извлечения всех книг из базы данных:

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

Перед этим создайте секрет токена доступа для подписи JWT, как и раньше:

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

На этом этапе давайте создадим промежуточное ПО Express, которое обрабатывает процесс аутентификации:

В этом промежуточном программном обеспечении мы читаем значение заголовка авторизации. Поскольку authorization имеет значение в формате Bearer [JWT_TOKEN] , мы разделили значение пробелом и разделили токен.

Затем мы проверили токен с помощью JWT. После проверки мы присоединяем user к запросу и продолжаем. В противном случае мы отправим клиенту ошибку.

Мы можем настроить это промежуточное ПО в нашем обработчике запросов GET, например:

Давайте загрузим сервер и проверим, все ли работает правильно:

Теперь мы можем отправить запрос на http://localhost:4000/books чтобы получить все книги из базы данных.

Убедитесь, что вы изменили заголовок «Authorization», чтобы он содержал значение «Bearer [JWT_TOKEN]», как показано на изображении ниже:

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

Мы также можем использовать промежуточное ПО для аутентификации, которое мы использовали выше:

Поскольку промежуточное программное обеспечение аутентификации связывает пользователя с запросом, мы можем получить role из req.user и просто проверить, является ли пользователь admin . Если да, то книга добавляется, в противном случае выдается ошибка.

Давайте попробуем это с нашим клиентом REST. Войдите в систему как admin (используя тот же метод, что и выше), а затем скопируйте accessToken и отправьте его с Authorization как мы сделали в предыдущем примере.

Затем мы можем отправить запрос POST в конечную точку http://localhost:4000/books

Обновление токена

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

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

Чтобы исключить эту возможность, давайте обновим наш обработчик запросов на вход, чтобы срок действия токена истекал через определенный период. Мы можем сделать это, передав expiresIn в качестве опции для подписи JWT.

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

Сначала создайте секрет токена обновления и пустой массив для хранения токенов обновления:

Когда пользователь входит в систему, вместо создания одного токена генерируйте токены обновления и аутентификации:

А теперь давайте создадим обработчик запросов, который генерирует новые токены на основе токенов обновления:

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

Чтобы этого избежать, реализуем простую функцию logout

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

Заключение

В этой статье мы познакомили вас с JWT и как реализовать JWT с Express. Я надеюсь, что теперь у вас есть хорошие знания о том, как работает JWT и как реализовать его в своем проекте.

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

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