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

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

Примечание. Код JavaScript для этой статьи доступен в следующем репозитории GitHub.

Цель статьи:предоставить разработчикам Node.JS практические инструменты и теорию для реализации аутентификации в вашем веб-приложении.

Краткая история: тогда и сейчас

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

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

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

С сохранением состояния против без гражданства

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

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

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

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

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

Проблема — клиентская сторона против серверной и проблема с учетными данными для входа

Каждое современное веб-приложение состоит из двух частей:

  1. Сторона клиента
  2. Серверная часть

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

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

Раньше разработчикам, которые писали клиентские приложения, нужно было сохранять в локальном кэше браузера (где-то еще) учетные данные (имя пользователя и пароль), чтобы проверить каждоесообщение HTTP-запроса, поступающее от клиента на сервер (то есть пользователь находится в состоянии «вошел в систему»).

***Помните, что на стороне сервера без сохранения состояния.

Решение — веб-токены JSON (JWT)

Вместо того, чтобы сохранять учетные данные пользователя (пользователь и пароль) на определенное время, давайте сохраним «токен» на стороне клиента, который закодирован из полезных данных с использованием секрета.

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

Веб-токены JSON представляют собой текстовые строки, которые могут использоваться клиентом и сервером для простой аутентификации и обмена информацией. Если вы помните необходимую аутентификацию, мы записываем информацию клиенту, записывая cookie как переменную сеанса. Однако в JWT токен кодируется из полезной нагрузки данных с использованием секрета. Этот токен передается клиенту. Всякий раз, когда клиент отправляет этот токен вместе с запросом, сервер проверяет его и отправляет ответ.

ПО промежуточного слоя Express.JS

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

Промежуточные функции — это функции, которые имеют доступ к объекту запроса (req), объекту ответа (res) и следующей функции промежуточного программного обеспечения в запросе приложения. цикл ответа. Следующая промежуточная функция обычно обозначается переменной с именем next.

Промежуточное ПО уровня приложения с использованием express-jwt

Привяжите промежуточное ПО уровня приложения к экземпляру объекта приложения с помощью функций app.use() и app.METHOD(), где METHOD — это HTTP-метод запроса, который обрабатывает функция промежуточного ПО (например, GET, PUT или POST) в нижнем регистре.

в этом примере мы используем библиотеку express-jwt

var jwt = require('express-jwt');

//ALLOW PATHS WITHOUT TOKEN AUTHENTICATION 
//Production : credentialsRequired: true 
//Development : credentialsRequired: false
app.use(expressJWT({ secret: secret, credentialsRequired: false }) 
.unless({ 
         path: [ 
               '/signup' 
               ] 
         } 
));

это означает, что каждый раз, когда наши учетные данные (JWT) *недействительны*, мы будем перенаправляться на путь регистрации\входа

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

https://developer.mozilla.org/en-US/docs/Web/HTTP/Аутентификация

Начальныйисходный код:

Бонус: разбираемся с CORS в Express.js

Бонус: коды HttpStatus

стоит знать, что HttpStatusCodes.

400 Bad RequestСервер не может понять запрос из-за неправильного синтаксиса

.401 UnauthorizedХотя в стандарте HTTP указано «неавторизованный», семантически этот ответ означает «не прошедший проверку подлинности». То есть клиент должен аутентифицировать себя, чтобы получить запрошенный ответ.

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

403 ForbiddenКлиент не имеет прав доступа к контенту; то есть он неавторизован, поэтому сервер отказывается предоставить запрошенный ресурс. В отличие от 401, личность клиента известна серверу.

404 Not FoundСервер не может найти запрошенный ресурс. В браузере это означает, что URL-адрес не распознан. В API это также может означать, что конечная точка действительна, но самого ресурса не существует. Серверы также могут отправлять этот ответ вместо 403, чтобы скрыть существование ресурса от неавторизованного клиента. Этот код ответа, вероятно, самый известный из-за его частого появления в Интернете.

405 Method Not AllowedМетод запроса известен серверу, но отключен и не может быть использован. Например, API может запретить УДАЛЕНИЕ ресурса. Два обязательных метода, GET и HEAD, ни в коем случае нельзя отключать, и они не должны возвращать этот код ошибки.

500 Internal Server ErrorСервер столкнулся с ситуацией, которую не знает, как поступить.

Заворачивать

Спасибо, что прочитали эту статью, не забудьте похлопать, если у вас что-то получилось!

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

Спасибо.