Русский
Русский
English
Статистика
Реклама

Guide

Интеграция Netsparker с AD через Keycloak

16.12.2020 14:07:22 | Автор: admin

Привет, Хабр!

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

Забегая вперед, стоит отметить, что аналогичные шаги помогут настроить интеграцию с AD не только Netsparker, но и иных приложений, которые не имеют собственных средств взаимодействия с Active Directory.

Netsparker это коммерческий динамический сканер веб-приложений, который позволяет обнаруживать большое количество уязвимостей в реальном времени и при этом располагает широким набором средств для интеграции с различными инструментами разработки и сборки. Это позволяет осуществлять поиск уязвимостей еще до того, как приложение выходит в производственную среду.
Подробнее: https://www.netsparker.com/

Keycloak решение с открытым кодом, которое способно выступать промежуточным звеном между приложением и сторонним аутентификационным сервисом. Это часто необходимо в случаях, если требования к аутентификации превосходят возможности приложения или имеющаяся инфраструктура позволяет сделать бесшовную аутентификацию между всеми используемыми сервисами (SSO).
Keycloak позволяет интегрировать ваши приложения с внешними системами аутентификации пользователей, может выступать в качестве посредника для использования social login сервисов и многое другое.
Подробнее: https://www.keycloak.org/

Проблема

По умолчанию в Netsparker есть несколько вариантов внедрения Single Sign-On: с Google Cloud, PingIdentity, Okta, Azure AD, ADFS, а также базовая интеграция при помощи SAML2.0.

В случаях, когда нет возможности использования вышеприведенных вариантов (например не разрешается применять ADFS, но тем не менее требуется интеграция с AD) можно использовать базовый вариант с SAML.

Проблема: Netsparker не работает напрямую с ADПроблема: Netsparker не работает напрямую с AD

Дальше я расскажу, как мы подключали чистый AD к Netsparker при помощи промежуточного инструмента Keycloak. Ниже будет представлен самый базовый вариант, так как в каждой организации процесс будет отличаться.

Общая схема выглядит так:

Схема интеграции Netsparker с AD через KeycloakСхема интеграции Netsparker с AD через Keycloak

Существует как минимум два режима работы. В первом режиме база пользователей AD синхронизируется с базой пользователей Keycloak, и система аутентификации Keycloak используется для разрешения доступа пользователям в Netsparker. Во втором режиме Keycloak берет на себя непосредственно аутентификацию пользователя в AD без сохранения данных пользователей в своей базе. При этом, если необходимо, можно вести базу пользователей (например которых нет в AD) дополнительно и в Keycloak.

Для того чтобы аутентификация в Netsparker была возможна, необходимо чтобы именем пользователя являлся его email-адрес. Это связано с особенностями пользовательской базы данных Netsparker, где каждая учетная запись определяется ее email-адресом. Знание этой особенности нам потребуется дальше.

Приступим.

Экспорт конфигурации Netsparker SSO

Первый шаг. Чтобы включить Single Sign-On в Netsparker необходимо сделать следующее:

  1. Войти в Netsparker под административным пользователем и открыть Settings Single Sign-On.

  2. Поставить флажок Enable для включения поддержки SSO.
    (!) Опция Enforce to authenticate ... нужна для того, чтобы запретить пользователям без прав администратора вход напрямую в Netsparker с использованием пароля.
    Остальные поля мы заполним чуть позже данными из Keycloak.

    Экран настройки Netsparker SSOЭкран настройки Netsparker SSO


    После включения функции SSO на странице входа в Netsparker появится дополнительная ссылка для доступа через внешний сервис.
    Вот так это будет выглядеть для неаутентифицированного пользователя:

    Экран входа в Netsparker для неаутентифицированного пользователяЭкран входа в Netsparker для неаутентифицированного пользователя
  3. Справа на закладке SAML скачиваем базовый XML с метаданными Netsparker.
    Этот XML содержит настройки SAML-клиента (в нашем случае им является Netsparker), которые понадобятся для конфигурирования Keycloak, например Client Identifier, SAML Service URL.

    Сохранение SAML мета-данных NetsparkerСохранение SAML мета-данных Netsparker

На данном этапе с Netsparker'ом всё. Переходим в Keycloak.

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

  1. Заходим в панель администратора Keycloak и создаем новый Realm с названием, например, Netsparker.
    Realm это раздел, в котором будет храниться вся конфигурация, касающаяся конкретно нашего приложения (Netsparker), включая настройки синхронизации с AD, собственная база пользователей и т. п.

    Экран добавления Realm'аЭкран добавления Realm'а
  2. Теперь необходимо в этом Realm прописать нашего клиента (Netsparker), который будет пользоваться услугами Keycloak.
    Переходим на закладку Clients, нажимаем Create, импортируем XML, который сохранили из Netsparker.

    Экран добавления клиента KeycloakЭкран добавления клиента Keycloak

    Данные формы подгрузятся из файла, поэтому нажимаем Save.

  3. В открывшемся экране настроек клиента сразу сохраняем себе в блокнот данные сертификата (закладка SAML Keys).

    Данные сертификата клиента KeycloakДанные сертификата клиента Keycloak
  4. Возвращаемся на закладку Settings и вносим следующие изменения:

    Client Signature Required ставим в положение OFF, т. к. Netsparker пока не передает данные о своем алгоритме подписи, и поэтому SAML-запрос получается некорректным.
    Valid Redirect URIs модифицируем URL и заменяем часть строки адреса ?spid на *. Это поле задает шаблон для адресов, на которые Keycloak разрешено осуществлять перенаправление браузера. Это сделано для того, чтобы злоумышленник не мог подставить адрес подконтрольного ему сервиса.

    Настройки клиента KeycloakНастройки клиента Keycloak


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

  5. Нажимаем Save и возвращаемся в Netsparker.

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

Теперь на стороне сканера добавляем данные о провайдере аутентификационных данных (сокращенно IdP), в нашем случае это Keycloak.

  1. Донастроим то, что мы начали настраивать на первых шагах.
    Снова открываем страницу Netsparker Settings Single Sign-On и прописываем идентификатор IdP и URL для SAML-запросов.

    У Keycloak эти значения стандартные:
    IdP Identifier:
    https://<домен-где-установлен-Keycloak>/auth/realm/<наш-Realm>
    SAML Endpoint:
    https://<домен-где-установлен-Keycloak>>/auth/realms/<наш-Realm>/protocol/saml
    X.509 Certificate:
    Сертификат в base64, который мы сохранили из Keycloak.

    Настройка SSO в NetsparkerНастройка SSO в Netsparker
  2. Сохраняем конфигурацию, и на данный момент у нас уже есть базовая возможность пользоваться аутентификацией Keycloak.

    При нажатии на Sign in via your Identity Provider открывается промежуточная форма ввода email пользователя из Netsparker, из которой уже осуществляется переход на форму входа Keycloak. Пользовательские данные, вводимые на этой форме либо проверяются в базе пользователей Keycloak, либо прокидываются дальше на AD (мы посмотрим оба варианта).

    После успешного входа в Keycloak нас должно перенаправить обратно в Netsparker уже в аутентифицированном состоянии.

    Процесс входа в NetsparkerПроцесс входа в Netsparker


    Но чтобы это произошло, надо сперва сконфигурировать пользователей.

Создание пользователей вручную

Netsparker

Для начала заведем тестового пользователя в Netsparker для проверки интеграции.

  1. В Netsparker открываем Team New Team Member, заполняем поля Name, Email и проставляем какие-нибудь разрешения (те, что на снимке, выбраны просто для примера):

    Экран создания пользователей в NetsparkerЭкран создания пользователей в Netsparker
  2. Активируем пользователя, кликнув на код подтверждения на странице Invitations.

    Список "приглашенных" пользователейСписок "приглашенных" пользователей
  3. На открывшейся странице вводим пароль для созданного пользователя и нажимаем Create an account.
    Этот пароль будет использоваться, только если пользователь решит войти в Netsparker не через SSO, а через обычную форму входа:

    Экран регистрации нового пользователя NetsparkerЭкран регистрации нового пользователя Netsparker

Keycloak

На данный момент войти в Netsparker через SSO не получится, т. к. в базе Keycloak в нашем Realm еще нет ни одного пользователя и Keycloak не сможет его аутентифицировать.

Исправим это:

  1. Заходим в Keycloak Manage Users, нажимаем Add user, вводим данные пользователя и сохраняем:

    Экран добавления пользователя в KeycloakЭкран добавления пользователя в Keycloak

    Здесь важно указать Username в виде email-адреса и поставить Email Verified в положение On, чтобы можно было бесшовно перейти от Keycloak к Netsparker.

  2. После сохранения появляется страница деталей пользователя. На ней в закладке Credentials необходимо установить пароль этому пользователю. Он при необходимости может отличаться от пароля в Netsparker:

    Создание пароля для пользователя KeycloakСоздание пароля для пользователя Keycloak

    Ставим Temporary в положение Off и устанавливаем пароль.

Промежуточная проверка интеграции

Теперь можем убедиться, что наша интеграция Netsparker+Keycloak работает:

  1. Открываем страницу входа в Netsparker и выбираем Sign in via your Identity Provider.

  2. Вводим почтовый адрес нашего тестового пользователя и попадаем на страницу входа в Keycloak.

  3. Указываем аутентификационные данные созданного пользователя.

    Экран входа в KeycloakЭкран входа в Keycloak
  4. Если всё прошло успешно, Keycloak перенаправит нас на главную страницу Netsparker под нашим тестовым пользователем.

    Перенаправление из Keycloak в NetsparkerПеренаправление из Keycloak в NetsparkerОсновной экран сканера NetsparkerОсновной экран сканера Netsparker

Промежуточный итог
Итак, на данный момент у нас есть возможность входить в Netsparker, вводя данные пользователя в Keycloak. Следующий шаг и реализация начальной цели связать аутентификацию Netsparker c аутентификацией на AD. При необходимости мы также можем синхронизировать базу данных пользователей Keycloak с базой Active Directory.

Следующий этап настройки: Keycloak + ADСледующий этап настройки: Keycloak + AD

Дорога в AD

Теперь сделаем следующий шаг и настроим аутентификацию пользователей Active Directory через Keycloak по LDAP. Для этого нам потребуется функция User Federation.

  1. Открываем Keycloak User Federation и в списке провайдеров выбираем ldap.

    Выбор провайдера аутентификации в KeycloakВыбор провайдера аутентификации в Keycloak
  2. Дальше настройка может отличаться в зависимости от конкретной структуры AD, но я опишу на базовом примере, что нам потребуется.

    В окне Add user federation provider заполняем поля:
    Vendor: Active Directory.
    Connection URL: путь к вашему серверу.
    Например ldap://172.16.2.23:389.
    Users DN: путь навигации к записям пользователя.
    Например CN=Users,DC=cx,DC=local.
    Bind DN: путь к записи администратора AD.
    Например cn=cxadmin,cn=users,dc=cx,dc=local.
    Bind Credential: пароль учетной записи администратора.
    Например ваш валидный пароль :)

    (!) Если мы хотим, чтобы данные из AD сперва синхронизировались в локальную базу Keycloak, ставим переключатель Import User в положение On.

    Опция импортирования пользователейОпция импортирования пользователей

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

  3. Дальше необходима небольшая манипуляция с данными из AD. Так как Netsparker требует в качестве имени пользователя его email-адрес (помните ремарку в начале?), нам надо убедиться, что во-первых из AD придут только пользователи с почтовым адресом и, во-вторых, что имя пользователя будет содержать этот адрес, а не иной параметр.

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

    Custom User LDAP Filter: (&(objectCategory=person)(mail=*)(objectClass=user)).
    Username LDAP attribute: mail.

    Сохраняем форму, и в итоге наш экран настройки должен выглядеть так:

    Сводная страница настроек LDAP провайдераСводная страница настроек LDAP провайдера
  4. Теперь сделаем так, чтобы при синхронизации пользователей AD они автоматически получали email в качестве имени пользователя. Для этого открываем закладку Mappers:

    Настройка mapper'овНастройка mapper'ов

    И в mapperе Username заменяем атрибут cn на mail.

    Настройка отображения email адреса на имя пользователяНастройка отображения email адреса на имя пользователя
  5. Сохраняем настройки.

(!) Если мы настраивали синхронизацию базы Keycloak с AD, мы можем проверить эту настройку, нажав Synchronize all users. Если всё прошло успешно, то на вкладке Users у нас появятся наши пользователи из AD'a:)

Проверяем, что всё работает

Можем убедиться, что наша настройка верна, войдя под учётной записью из AD в Netsparker.

  1. Проверяем, что в Netsparker есть пользователь с таким почтовым адресом (Manage Team). Какой у него пароль неважно, так как аутентификация будет происходить на стороне AD.

    Искомый пользователь NetsparkerИскомый пользователь Netsparker
  2. Открываем страницу Netsparker SSO и вводим email-адрес пользователя AD.

    Промежуточный экран входа в Netsparker SSOПромежуточный экран входа в Netsparker SSO
  3. На странице входа Keycloak вводим данные пользователя AD с паролем.

    Экран входа в KeycloakЭкран входа в Keycloak
  4. Нам должна открыться страница Netsparker для этого пользователя.

    Основной экран Netsparker для аутентифицированного AD-пользователя AlexОсновной экран Netsparker для аутентифицированного AD-пользователя Alex

Настройка автоматического создания пользователей

Вручную заводить новых пользователей зачастую неудобно, поэтому в Netsparker есть возможность упростить заведение новых учётных записей, которая называется auto provisioning. С ее помощью устраняется необходимость вручную добавлять нового пользователя: если его нет в базе данных Netsparker, то такой пользователь будет создан автоматически при попытке входа с верными данными своей учётной записи AD.

Дальше нам будет необходимо сделать небольшие изменения в конфигурациях Keycloak и Netsparker. Так как auto provisioning требует, чтобы сессия инициировалась Identity Provider'ом, давайте его и настроим:

Keycloak

  1. Открываем настройки нашего клиента Keycloak Clients наш клиент.

  2. Нам потребуется внести изменения в три поля:
    Valid Redirect URIs (опционально): можно оставить как было, а можно ограничить перенаправление конкретным клиентом (который задаётся параметром spid). Для этого копируем из настроек SSO Netsparke'а полный URL SAML 2.0 Service URL.
    IDP Initiated SSO URL: необходимо задать URL, который мы хотим использовать для нашего конкретного клиента (Netsparker), чтобы явно указать, что должно использоваться SSO, вызываемое со стороны IdP. Например netsparker. После этого пользователи смогут входить конкретно в Netsparker, используя URL из подсказки.
    Assertion Consumer Service POST Binding URL: URL, куда Keycloak будет отправлять SAML-данные для входа в Netsparker. Указываем здесь SAML 2.0 Service URL из настроек Netsparker'a.

    Дополнительная настройка клиента KeycloakДополнительная настройка клиента Keycloak
  3. Сохраняем настройки.

Настройка mappers

Чтобы Keycloak формировал SAML-запрос в виде, необходимом Netsparker'у, необходимо добавить в него несколько обязательных полей (FirstName и LastName). В этом нам поможет mapper, который автоматически назначит полям SAML соответствующие поля из пользовательской записи.

Для этого открываем Keycloak Clients Mappers и создаем mapper, нажав на Create.

Дополнительная настройка mapper'овДополнительная настройка mapper'ов

Содержимое полей mapper задаем как на картинке ниже:

Настройка SAML-mapper'а для имени пользователяНастройка SAML-mapper'а для имени пользователя

Аналогично создаём mapper для фамилии:

Настройка SAML-mapper'а для фамилии пользователяНастройка SAML-mapper'а для фамилии пользователя

Итоговый список должен выглядеть так:

Список mapper'овСписок mapper'ов

Netsparker

Последнее, что нам нужно сделать донастроить Netsparker, чтобы он создавал пользователей и принимал запросы на это действие от Keycloak.

  1. Открываем Netsparker Settings Single Sign-On.

  2. В поле SAML 2.0 Endpoint указываем URL из Keycloak из подсказки поля IDP Initiated SSO URL.

  3. Выбираем опцию Enable Auto Provisioning и сохраняем настройки.

    Настройка автоматического создания пользователей в NetsparkerНастройка автоматического создания пользователей в Netsparker

Финальная проверка

Теперь проверим как это всё работает.

  1. Прежде всего теперь на странице Netsparker Team можем удалить пользователя AD, которого мы создавали вручную.

    Удаление пользователяУдаление пользователя
  2. В Keycloak завершаем все сессии, чтобы они нам не мешали: Keycloak Manage Sessions Logout all.

  3. Открываем страницу Keycloak для SSO (напомню, Target IDP initiated SSO URL это ссылка вида:
    https://yourdomain.com/auth/realms/netsparker/protocol/saml/clients/netsparker).

  4. Вводим данные пользователя из AD.

  5. Если всё прошло успешно, в Netsparker будет создан соответствующий пользователь с минимальными правами и для него будет установлена новая сессия.

    Основной экран Netsparker для пользователя, автоматически созданного при входе через ADОсновной экран Netsparker для пользователя, автоматически созданного при входе через AD

Что дальше?

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

Если была выбрана опция auto provisioning, необходимо от имени административного пользователя выдать необходимые разрешения созданному пользователю, чтобы тот мог работать с Netsparker.

Для простоты лучше первый раз для создания пользователя входить через Target IDP initiated SSO URL и уже впоследствии аутентифицироваться либо по этому же URL, либо осуществлять вход через привычную страницу Netsparker Login.

Еще один нюанс в данный момент выход пользователя из Netsparker не приводит к выходу пользователя из Keycloak. Поэтому, когда в следующий раз мы решим войти при помощи SSO, нас сразу перебросит в Netsparker под последним аутентифицированным пользователем. Это можно решить, например, уменьшив длительность сессии пользователя в Keycloak. Тогда его SSO-сессия будет автоматически уничтожена после указанного промежутка времени.
Настройка осуществляется в Realms Netsparker Tokens:

Настройка длительности SSO сессииНастройка длительности SSO сессии

Также пользователь может вручную закончить свою сессию на собственной странице учётной записи Keycloak по ссылке вида: https://keycloak.yourcompany.com/auth/realms/netsparker/account
После этого для входа в Netsparker потребуется снова аутентифицироваться в Keycloak и можно будет осуществить вход под другим пользователем.

Заключение

Мы рассмотрели в деталях, как можно аутентифицировать пользователей Netsparker через Active Directory с использованием промежуточного решения Keycloak. В принципе, такой же процесс может быть применён и для других приложений, которые не работают с Active Directory напрямую, но поддерживают SAML для описания деталей аутентификации.
Keycloak позволяет достаточно гибко настраивать и дополнять систему аутентификации, комплексно закрывая этот аспект безопасности для приложений, используемых в организации.

Подробнее..

Краткое руководство по Node.js для начинающих (SPA, PWA, mobile-first)

15.08.2020 14:04:40 | Автор: admin


Доброго времени суток, друзья!

Представляю вашему вниманию перевод Руководства по Node.js в формате одностраничного прогрессивного адаптированного приложения.

Данный формат означает следующее:

  • SPA новые данные (разделы или главы руководства) загружаются без перезагрузки страницы реализовано с помощью динамического импорта
  • PWA приложение можно установить на мобильный телефон или компьютер; приложение работает даже при отсутствии подключения к сети реализовано с помощью сервис-воркера и кэширования
  • mobile-first приложение предназначено для использования, в первую очередь, на смартфонах, но хорошо выглядит и на широких экранах

Посмотреть и установить приложение можно здесь: Netlify, PWA Store.

Код проекта на GitHub.

Песочница:


На десктопе приложение выглядит так:





А на смартфоне так:







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

Оригинальное руководство написано в 2019 году с учетом последней на тот момент версии Node.js и ES2018, что обуславливает его актуальность.

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

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

Страницы переключаются с помощью кнопок и клавиатуры.

Для стилизации приложения использовался Materialize.

Несколько слов о реализации

Реализация приложения до неприличия проста.

Каждый раздел (глава) представляет собой модуль следующего содержания:

export default `разметка и текст`

В разметке главной страницы у нас имеются ссылки:

<a class="link" data-url="1" href="#">1. Введение</a>

и кнопки:

<!-- классы фреймворка удалены --><button>    <i class="left">navigate_before</i></button><button>    <i class="right">navigate_after</i></button>

При нажатии на ссылку или кнопку вызывается функция отображения страницы, которой передается номер страницы. При инициализации приложения номер страницы запрашивается из локального хранилища. При отсутствии такового, номер страницы = 1. При нажатии на ссылку номером страницы становится значение атрибута data-url ссылки. При нажатии на кнопку номер страницы увеличивается или, соответственно, уменьшается на 1. Сама функция выглядит так:

const showPage = i => {    // определяем адрес запрашиваемой страницы    const url = `./chapters/${i}.js`    // импортируем соответствующий модуль    import(url)        // вставляем разметку в основной контейнер        .then(data => container.innerHTML = data.default)    // записываем номер страницы в локальное хранилище    localStorage.setItem('NodejsGuidePageNumber', i)    // прокручиваем страницу    scrollTo(0, 0)}

Вот и все, как видите, ничего особенного. Первые две строки кода это навигационная панель Materialize. О сервис-воркерах можно почитать здесь.

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

Надеюсь, приложение вам понравится. Благодарю за внимание.
Подробнее..

Перевод Руководство по Express.js. Часть 1

27.08.2020 12:18:32 | Автор: admin


Доброго времени суток, друзья!

Представляю вашему вниманию перевод первой части Руководства по Express веб-феймворку для Node.js автора Flavio Copes.

Предполагается, что вы знакомы с Node.js. Если нет, то прошу сюда.

Без дальнейших предисловий.

1. Введение


Express это веб-фреймворк для Node.js.

Node.js замечательный инструмент для создания сетевых сервисов и приложений.

Express использует возможности Node.js, значительно облегчая процесс создания веб-сервера.

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

2. Установка


Express можно установить с помощью npm:

npm i express

Или yarn:

yarn add express

Для инициализации нового проекта выполните команду npm init или yarn init. Для автоматического заполнения полей следует добавить флаг -y.

3. Hello World


Мы готовы к созданию нашего первого сервера.

Вот его код:

const express = require('express')const app = express()app.get('/', (req, res) => res.send('Hello World!'))app.listen(3000, () => console.log('Сервер запущен'))

Сохраните этот код в файле index.js и запустите сервер:

node index.js

Откройте браузер на localhost:3000 и увидете сообщения Hello World! на экране и Сервер запущен в консоли.

4. Основы Express


Эти 4 строки кода делают множество вещей за кулисами.

Сначала мы импортируем библиотеку express.

Затем инициализируем приложение, вызывая метод app().

После получения объекта приложения мы указываем ему обрабатывать GET-запросы к пути "/" с помощью метод get().

Для каждого HTTP-метода или, как еще говорят, глагола (хотя среди методов встречаются и существительные) имеется соответствующий метод Express:

app.get('/', (req, res) => {})app.post('/', (req, res) => {})app.put('/', (req, res) => {})app.delete('/', (req, res) => {})app.patch('/', (req, res) => {})

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

Мы передаем его так:

(req, res) => res.send('Hello World!')

Аргументы req и res соответствуют объектам Request (запрос) и Response (ответ).

Request содержит информацию о запросе, включая параметры, заголовки, тело запроса и т.д.

Response это объект, отправляемый клиенту в ответ на запрос.

В нашем коде мы отправляем клиенту строку Hello World! с помощью метода Response.send().

Данный метод помещает строку в тело ответа и закрывает соединение.

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

6. Параметры запроса


Объект Request содержит информацию о запросе.

Ниже приведены основные свойства этого объекта.
Свойство Описание
.app содержит ссылку на объект приложения
.baseUrl содержит ссылку на экземпляр маршрутизатора (express.Router())
.body содержит данные, помещенные в тело запроса (должны быть разобраны (parsed) и заполнены (populated) перед использованием)
.cookies содержит куки, установленные в запросе (требуется промежуточное программное обеспечение (далее ППО) cookie-parser)
.hostname название хоста сервера
.ip IP-адрес сервера
.method метод запроса
.params объект с именованными параметрами запроса (например, при запросе к /users/:id, id будет записано в req.params.id)
.path URL запроса
.protocol протокол запроса
.query объект с параметрами строки запроса (например, при запросе к /search?name=john, john будет записано в req.query.name)
.secure содержит true, если запрос является безопасным (если используется HTTPS)
.signedCookies содержит подписанные куки (требуется ППО cookie-parser)
.xhr содержит true, если запрос это XMLHttpRequest

7. Получение параметров из строки запроса


Строка запроса это часть URL после вопросительного знака (?).

Например:

?name=john

Несколько параметров могут передаваться с помощью амперсанда (&):

?name=john&age=30

Как извлечь эти значения?

Это делается посредством распаковывания объекта Request.query:

const express = require('express')const app = express()app.get('/', (req, res) => {    console.log(req.query)})app.listen(8080)

Данный объект содержит свойство для каждого параметра строки запроса.

Если параметры отсутствуют, объект является пустым.

Перебрать объект можно с помощью цикла for/in:

for (const key in req.query) {    console.log(key, req.query[key])}

Этот код выведет в консоль ключи и значения параметров строки запроса.

Также можно получить значение конкретного параметра:

req.query.name // johnreq.query.age // 30

8. Получение параметров строки POST-запроса


Параметры строки POST-запроса предоставляются клиентом при отправке формы или других данных.

Как нам получить эти параметры?

Если данные были отправлены в формате JSON с помощью Content-Type: application/json, такие данные необходимо разобрать с помощью ППО express.json(). ППО подключается с помощью метода app.use():

const express = require('express')const app = express()app.use(express.json())

Если данные были отправлены в формате JSON с помощью Content-Type: application/x-www-urlencoded, такие данные необходимо разобрать с помощью ППО express.urlencoded():

const express = require('express')const app = express()app.use(express.urlencoded())

В обоих случаях данные можно получить через Request.body:

app.post('/form', (req, res) => {    const name = req.body.name})

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

9. Отправка ответа


Как отправить ответ клиенту?


В приведенном примере мы использовали метод Response.send() для отправки клиенту ответа в виде строки и закрытия соединения:

(req, res) => res.send('Hello World!')

При передачи строки, заголовок Content-Type устанавливается в значение text/html.

При передачи объекта или массива, заголовок Content-Type устанавливается в значение application/json, а данные преобразуются в формат JSON.

send() также автоматически устанавливает заголовок Content-Length и закрывает соединение с сервером.

Использование end() для отправки пустого ответа


Альтернативным способом отправки клиенту ответа, не содержащего тела, является использование метода Response.end():

res.end()

Установка статуса ответа


Для этого используется метод Response.status():

res.status(404).end()

Или:

res.status(404).send('Файл не найден')

sendStatus() является сокращением для res.status().send():

res.sendStatus(200) // === res.status(200).send('Ok')res.sendStatus(403) // === res.status(403).send('Forbidden')res.sendStatus(404) // === res.status(404).send('Not Found')res.sendStatus(500) // === res.status(500).send('Internal Server Error')

10. Отправка ответа в формате JSON


При обработке запросов маршрутизатором колбек вызывается с двумя параметрами экземпляром объекта Request и экземпляром объекта Response.

Например:

app.get('/', (req, res) => res.send('Hello World!'))

Здесь мы используем метод Response.send(), принимающий строку.

Ответ клиенту в формате JSON можно отправить с помощью метода Response.json().

Данный метод принимате объект или массив и конвертирует его в JSON:

res.json({ name: 'John' }) // { "name": "John" }

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

Следите за обновлениями. Благодарю за внимание и хорошего дня.
Подробнее..

Перевод Руководство по Express.js. Часть 3

12.09.2020 16:16:00 | Автор: admin


Доброго времени суток, друзья!

Представляю вашему вниманию перевод второй части Руководства по Express веб-феймворку для Node.js автора Flavio Copes.

Предполагается, что вы знакомы с Node.js. Если нет, то прошу сюда.

Без дальнейших предисловий.

15. Шаблонизация


Express умеет работать с серверными шаблонизаторами (server-side template engines).

Шаблонизатор позволяет динамически генерировать HTML-разметку посредством передачи данных в представление (view).

По умолчанию Express использует шаблонизатор Pug, который раньше назывался Jade.

Несмотря на то, что с момента выхода последней версии Jade прошло почти 3 года, он все еще поддерживается в целях обеспечения обратной совместимости.

В новых проектах следует использовать Pug или другой шаблонизатор. Вот официальный сайт Pug: pugjs.org.

Среди других шаблонизаторов, можно назвать Handlebars, Mustache, EJS и др.

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


Для использования Pug, его сначала нужно установить:

npm i pug 

Затем его следует добавить в Express:

const express = require('express')const app = express()app.set('view engine', 'pug')

После этого мы можем создавать шаблоны в файлах с расширением .pug.

Создадим представление about:

app.get('/about', (req, res) => {    res.render('about')})

И шаблон в views/about.pug:

p Привет от Pug 

Данный шаблон создаст тег p с текстом Привет от Pug.

Интерполировать переменные можно так:

app.get('/about', (req, res) => {    res.render('about', { name: 'Иван' })})

p #{name} говорит привет

Подробнее о Pug мы поговорим в следующем разделе.

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

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


Попробуем использовать Handlebars вместо Pug.

Устанавливаем его с помощью npm i handlebars.

В директории views создаем файл about.hbs следующего содержания:

{{name}} говорит привет 

Перепишем код Express:

const express = require('express')const app = express()const hbs = require('hbs')app.set('view engine', 'hbs')app.set('views', path.join(__dirname, 'views'))app.get('/about', (req, res) => {    res.render('about', { name: 'Иван' })})app.listen(3000, () => console.log('Сервер готов'))

Вы также можете рендерить React на стороне сервера с помощью пакета express-react-views.

Устанавливаем данный пакет:

npm i express-react-views

Теперь вместо Handlebars укажем Express использовать express-react-views в качестве движка для обработки jsx-файлов:

const express = require('express')const app = express()app.set('view engine', 'jsx')app.engine('jsx', require('express-react-views').createEngine())app.get('/about', (req, res) => {    res.render('about', { name: 'Иван' })})app.listen(3000, () => console.log('Сервер запущен'))

В директории views создаем файл about.jsx:

const React = require('react')class HelloMessage extends React.Component {    render() {        return <div>{this.props.name} говорит привет</div>    }}module.exports = HelloMessage

16. Справочник по Pug


Что такое Pug? Это шаблонизатор или движок для динамического рендеринга HTML-разметки, используемый Express по умолчанию.

Установка:

npm i pug

Настройка Express:

const path = require('path')cpnst express = require('express')const app = express()app.set('view engine', 'pug')app.set('views', path.join(__dirname, 'views'))app.get('/about', (req, res) => {    res.render('about', { name: 'Иван' })})

Шаблон (about.pug):

p #{name} говорит привет 

Передача функции, возвращающей значение:

app.get('about', (req, res) => {    res.render('about', { getName: () => 'Иван' })})

p #{getName()} говорит привет 

Добавление элементу идентификатора или класса:

p#title p.title 
Установка doctype:

doctype html 

Мета-теги:

html     head         meta(charset='utf-8')        meta(http-equiv='X-UA-Compatible', content='IE=edge')        meta(name='description', content='Описание')        meta(name='viewport', content='width=device-width, initial-scale=1')

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

html     head         link(rel="stylesheet", href="style.css")        script(src="script.js", defer)

Встроенные скрипты:

    script alert('тест')        script        (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]= function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date; e=o.createElement(i);r=o.getElementsByTagName(i)[0]; e.src='//www.google-analytics.com/analytics.js'; r.parentNode.insertBefore(e,r)}(window,document,'script','ga')); ga('create','UA-XXXXX-X');ga('send','pageview');

Циклы:

ul     each color in ['Red', 'Green', 'Blue']        li= colorul     each color, index in ['Red', 'Green', 'Blue']        li= 'Номер цвета ' + index + ':' + color

Условия:

if name     h2 #{name} говорит привет else    h2 Привет if name    h2 #{name} говорит привет else if anotherName    h2 #{anotherName} говорит привет else    h2 Привет 

Переменные:

- var name = 'Иван'- age = 30 - var petr = { name: 'Петр' }- var friends = ['Иван', 'Петр']

Инкремент:

age++

Приваивание переменной элементу:

p= name span= age 

Перебор переменных:

for friend in friends     li= friendul     each friend in friends         li= friend 
Получение количества элементов:

p #{values.length}

While:

- var n = 0ul     while n <= 5        li= n++

Включение одного файла в другой:

include otherfile.pug 

Определение блоков.

Хорошо организованная система шаблонов предполагает создание базового шаблона и его расширение другими шаблонами по мере необходимости.

Базовый шаблон расширяется с помощью блоков:

html    head        link(rel="stylesheet", href="style.css")        script(src="script.js", defer)        body            block header                        block main                h1 Домашняя страница                p Добро пожаловать                        block footer

Расширение базового шаблона.

Шаблон расширяется с помощью ключевого слова extends:

extends home.pug 

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

extends home.pug block main     h1 Другая страница    p Привет     ul        li Раз элемент списка        li Два элемент списка 

Можно переопределять как один, так и несколько блоков. Те блоки, которые не переопределяются, сохраняют оригинальное содержимое.

Комментарии.

Видимые (сохраняются в разметке):

// однострочный комментарий//    многострочный    комментарий

Невидимые (удаляются при рендеринге):

//- однострочный комментарий//-     многострочный    комментарий

17. Middleware (промежуточный слой, промежуточное программное обеспечение)


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

Обычно, middleware применяется для обработки запроса/ответа либо для перехвата запроса перед его обработкой роутером. Middleware в общем виде выглядит так:

app.use((req, res, next) => {/* */})

Метод next() служит для передачи запроса следующему middleware, если в этом есть необходимость.

Если опустить next() в middleware, то обработка ответа завершится и он будет отправлен клиенту.

Middleware редко пишется вручную, как правило, в качестве таковых используются npm-пакеты.

Примером подобного пакета является cookie-parser, применяемый для преобразования куки в объект req.cookies. Данный пакет устанавливается с помощью npm i cookie-parser и используется следующим образом:

const express = require('express')const app = express()const cookieParser = require('cookie-parser')app.get('/', (req, res) => res.send('Привет!'))app.use(cookieParser())app.listen(3000, () => console.log('Сервер готов'))

Middleware может использоваться в определенном маршрутизаторе. Для этого он передается роутеру в качестве второго аргумента:

const myMiddleware = (req, res, next) => {    // ...     next()}app.get('/', myMiddleware, (req, res) => res.send('Привет!'))

Для того, чтобы сохранить данные, сформированные middleware, для их передачи другим middleware или обработчику запроса, используется объект Request.locals. Он позволяет записывать данные в текущий запрос:

req.locals.name = 'Иван'

18. Обработка статических файлов


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

const express = require('express')const app = express()app.use(express.static('public'))// ... app.listen(3000, () => console.log('Сервер готов'))

Если в директории public имеется файл index.html, он будет отправлен в ответ на запрос к localhost:3000.

19. Отправка файлов


Express предоставляет удобный метод для отправки файлов в ответ на запрос Reaponse.download().

После обращения клиента к маршруту, отправляющему в ответ файл, клиенту будет направлен запрос на скачивание файла.

Метод Response.download() позволяет отправлять файлы в ответ на запрос вместо отображения страницы:

app.get('/', (req, res) => res.download('./file.pdf'))

В контексте приложения это выглядит так:

const express = require('express')const app = express()app.get('/', (req, res) => res.download('./file.pdf'))app.listen(3000, () => console.log('Сервер готов'))

При отправке файла можно определить его название:

res.download('./file.pdf', 'some-custom-name.pdf')

Третим параметром рассматриваемого метода является колбэк, вызываемый после отправки файла:

res.download('./file.pdf', 'some-custom-name.pdf', error => {    if (error) {        // обрабатываем ошибку    } else {        console.log('Файл успешно отправлен')    }})

20. Сессии


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

Пользователи не могут быть идентифицированы нативными средствами.

Вот где в игру вступают сессии.

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

Мы будем использовать express-session, поддерживаемый командой Express.

Устанавливаем его:

npm i express-session

Инициализируем:

const session = require('express-session')

Добавляем в Express в качестве middleware:

const express = require('express')const session = require('express-session')const app = express()app.use(session(    'secret': '343ji43j4n3jn4jk3n'))

После этого все запросы к приложению будут сессионными.

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

Сессия включается в состав запроса, доступ к ней можно получить через req.session:

app.get('/', (req, res, next) => {    // req.session })

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

req.sessions.name = 'Иван'console.log(req.sessions.name) // Иван 

При записи данные сериализуются (преобразуются в формат JSON), так что можно смело использовать вложенные объекты.

Сессии используются для передачи данных другим middleware или для их извлечения при последующих запросах.

Где хранятся сессионные данные? Это зависит от того, как настроен модуль express-session.

Такие данные могут храниться в:

  • памяти только при разработке
  • базе данных, например, MySQL или Mongo
  • кэше, например, Redis или Memcached

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

По идентификатору сервер осуществляет поиск хранящихся на нем данных.

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

Лучшим решением является Redis, однако, она требует дополнительной настройки инфраструктуры.

Другим популярным решением является пакет cookie-session. Он сохраняет данные в куки на стороне клиента. Данный способ использовать не рекомендуется, поскольку данные будут включаться в каждый запрос клиента и размер данных ограничен 4 Кб. Кроме того, обычные куки не подходят для хранения конфиденциальной информации. Существуют безопасные куки, передаваемые по протоколу HTTPS, но такие куки требуют дополнительной настройки с помощью прокси-сервера.

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

Следите за обновлениями. Благодарю за внимание и хороших выходных.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru