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

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

Я придумал этот подход при создании приложения для электронной коммерции. Прежде чем написать какую-либо строчку кода, мне нужно было определить пользователей и возможные страницы, к которым они могут получить доступ в моем приложении, и на тот момент я взглянул на awesome-nuxt (https://github.com/nuxt -community / awesome-nuxt ) я обнаружил репозиторий auth-module и попытался использовать его. Это была замечательная работа, но она не соответствовала моим требованиям. Итак, я пошел под капот, посмотрел, как это работает, и добавил несколько настроек. При этом этот подход был построен из репозитория auth-module.

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

  • Плагины
  • Промежуточное ПО
  • Контекст
  • Vuex в Nuxt
  • Маршрутизация
  • SSR (рендеринг на стороне сервера)

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

  • Что мы защищаем?
  • Где мы размещаем наши меры безопасности?
  • Как мы идентифицируем и отличим наших пользователей?
  • Как будут действовать наши меры безопасности?

ЧТО МЫ ЗАЩИЩАЕМ

Это простой вопрос, и ответом на него будет все наше приложение. Под всем приложением это будет означать среду выполнения сервера и браузера для УНИВЕРСАЛЬНОГО режима и только среду выполнения браузера для режима SPA. Я больше сосредоточусь на режиме UNIVERSAL / SSR, потому что в этом и вся сила, и если мы сможем идеально защитить приложение в таком разделенном состоянии, для режима SPA это не проблема. На всякий случай вам интересно, что значило бы создать приложение с SSR. Это просто означает обслуживание ваших веб-страниц с сервера (как в старые добрые времена PHP Apache C-Panel), и это дает следующие преимущества:

  • Возможность кодирования некоторых функций серверной части в приложении внешнего интерфейса (вы можете сделать свое приложение внешнего интерфейса собственной серверной службой, взяв на себя некоторые из тяжелых нагрузок от фактической серверной службы для выполнения избыточных задач, таких как анализ местоположения IP и многое другое).
  • Повышает производительность (это также улучшит производительность на сайтах с большим количеством контента, потому что вы можете настроить данные, необходимые на страницах, которые будут извлекаться на стороне сервера вашего приложения, где они богаты ресурсами, тогда все, что нужно сделать браузеру, это отобразить HTML ).
  • И многое другое.

Таким образом, защита нашего приложения в УНИВЕРСАЛЬНОМ режиме означает включение защиты на нашем сервере при первом запросе и на клиенте при последующих обращениях.

ГДЕ МЫ РАЗМЕЩАЕМ МЕРЫ БЕЗОПАСНОСТИ

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

КАК МЫ ИДЕНТИФИКАЕМ И ОТЛИЧАЕМ НАШИ ПОЛЬЗОВАТЕЛЕЙ

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

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

  • Vuex
  • Сохраненное состояние Vuex
  • js-cookie (библиотека файлов cookie для браузера)
  • cookie (библиотека cookie для Nodejs (Сервер))

По умолчанию Vuex используется для хранения состояния нашего приложения, поскольку он служит единым хранилищем истины для общих данных в нашем приложении, и, поскольку он понадобится нам как на клиенте, так и на сервере, мы бы обернули его с сохраненным состоянием Vuex. поскольку он позволяет нам читать / записывать наше хранилище Vuex в постоянное хранилище, чтобы оно было доступно даже при обновлении нашего приложения. Последний вопрос: какое хранилище? Используемое нами хранилище - это файлы cookie, поскольку файлы cookie используются сервером и браузером совместно. Примечание: поскольку хранилище файлов cookie не очень велико, нам нужно будет сократить наши сохраненные данные до пользовательской информации, любая другая информация, которая может потребоваться, может быть сохранена на клиенте с локальным хранилищем, потому что теперь мы в конечном итоге используем наше хранилище Vuex для идентификации. На всякий случай, если вас не устраивают эти ограничения, вы можете настроить сохраняемое состояние Vuex на свой вкус, основная концепция здесь заключается в том, что состояние аутентификации должно храниться во Vuex, а состояние Vuex, связанное с аутентификацией, должно совместно использоваться сервером. и браузер, использующий файлы cookie.

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

КАК БУДЕТ РАБОТАТЬ НАША БЕЗОПАСНОСТЬ

Теперь о хорошем, наших охранниках. Их принцип работы прост. Каждый зарегистрированный в приложении маршрут является ресурсом. Мы группируем каждый ресурс на основе наших категорий пользователей. например, admin_routes, guest_routes, customer_routes и т. д. Затем, в зависимости от категории пользователя, мы позволяем пользователю пройти, соответственно, или перенаправляем, если есть несоответствие. Это основной способ выразить это. Подождите, я слышал, вы сказали, что хотите подробностей?

Хорошо, вот еще что. Теперь, после категоризации, мы должны определить данные запроса, которые будут содержать всю информацию о входящем запросе. К счастью, промежуточное ПО Nuxt по умолчанию предоставляет большинство значений, таких как From (маршрут, из которого исходит запрос (только среда выполнения браузера)), To (маршрут, на который направляется запрос (обе среды выполнения)), User Data (необходимые данные пользователя для идентификации пользователь (обе среды выполнения)). Итак, с нашими данными маршрута идея состоит в том, чтобы предположить работу конвейерной ленты в производственной компании. Немного запутались ?. Позволь мне объяснить.

На иллюстрации выше каждый документ представляет собой данные нашего запроса, а узел обработки - это единый защитник маршрута, настроенный для обработки данных запроса, относящихся к его конкретной группе маршрутов. Это означает, что представьте, что это изображение имеет так много узлов обработки, и каждый узел будет содержать код для обнаружения и перенаправления соответственно для одной группы маршрутов, и когда он будет обработан, запросы будут переданы следующему узлу и так далее, как много групп маршрутов, пока не дойдет до конца. Мы бы назвали это конвейером Navigation Guard. Из приведенных выше примеров групп маршрутов, поскольку мы указали только 3 маршрута (admin_routes, guest_routes, customer_routes), у нас будет только 3 узла. Паттерн, который я пытаюсь описать здесь, представляет собой парадигму функционального программирования под названием «Композиция», но с небольшим поворотом. Хитрость заключается в том, что функциональная парадигма использует данные, которые должны оставаться неизменными, и на каждом узле обработка выполняется и передается следующему узлу, при этом данные остаются нетронутыми, поскольку предполагается, что они не имеют состояния. Наша реализация не может работать таким образом, наши данные должны быть блестяще обновлены, чтобы запросы, которые должны обрабатываться на конкретном узле, не были повторно обработаны на другом узле, поскольку каждый узел должен быть построен так, чтобы функционировать, не зная о других. узлов (стиль Plug n Play). Реалистичным примером может быть прямая линия охранников, каждый из которых находится в разных местах в здании. Тогда посетитель, который направляется в комнату B, сделает отметку в своей карточке посетителя. Когда карта будет сканирована охранником для комнаты A, он просто пропустит и передаст ее охраннику для комнаты B, который распознает эту карту, пометит ее как обработанную, и тогда оставшиеся охранники не будут смотреть на нее, так как посетитель посетил до, то в конце очереди охранников теперь будет проводник, который проведет посетителя к месту назначения. Это в основном то, что будет делать Navigation Pipeline. Наконец, окончательный вывод нашего конвейера теперь будет передан методу перенаправления, который будет читать выходные данные и знать, как соответствующим образом перенаправить запрос.

Ух! Это было давно. Я очень надеюсь, что вы последовали моему примеру, постарайтесь как можно лучше понять операцию, используя приведенные примеры сценариев, поскольку они будут ключевыми на следующем этапе статьи, где мы превратим всю эту теорию в правильный код. Но знаете, настоящий гений получил бы все, что нужно для его реализации, из этой статьи, посмотрите, сможете ли вы справиться с этим самостоятельно. Примечание. Этот подход структурирован для масштабирования, помните, я придумал его для приложения электронной коммерции. Если это чрезмерная инженерия для вашего приложения, не стесняйтесь делать то, что считаете нужным, но я сомневаюсь, что вам это понадобится. Удачного кодирования.