WEB работает по протоколу HTTP, который не хранит состояние: каждый HTTP запрос ничего не знает о том, что происходило до этого.

Для начала чем отличается аутентификация и авторизация.

  • Аутентификация — это проверка вашей личности. Когда вы входите в приложение с именем и паролем, вы аутентифицируетесь.
  • Авторизация — это проверка наличия у вас доступа к чему-либо. Это может быть набор разрешений на какие-то действия. Например, если вы создали в приложении ресурс, то вы можете быть единственным, кому разрешено удалять этот ресурс (потому что вы владелец), а другие пользователи для того не «авторизованы».

Аутентификация на основе сессий

Состояние отслеживается

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

Процедура аутентификации на основе сессий:

  1. Пользователь вводит в браузере своё имя и пароль, после чего клиентское приложение отправляет на сервер запрос.
  2. Сервер проверяет пользователя, аутентифицирует его, шлёт приложению уникальный пользовательский токен (сохранив его в памяти или базе данных).
  3. Клиентское приложение сохраняет токены в куках и отправляет их при каждом последующем запросе.
  4. Сервер получает каждый запрос, требующий аутентификации, с помощью токена аутентифицирует пользователя и возвращает запрошенные данные клиентскому приложению.
  5. Когда пользователь выходит, клиентское приложение удаляет его токен, поэтому все последующие запросы от этого клиента становятся неаутентифицированными.

Аутентификации на основе сессий

Недостатки:

  • При каждой аутентификации пользователя сервер должен создавать у себя запись. Обычно она хранится в памяти, и при большом количестве пользователей есть вероятность слишком высокой нагрузки на сервер.
  • Поскольку сессии хранятся в памяти, масштабировать не так просто. Если вы многократно реплицируете сервер, то на все новые серверы придётся реплицировать и все пользовательские сессии. Это усложняет масштабирование. (Я считал, этого можно избежать, если иметь выделенный сервер для управления сессиями, но это сложно реализовать, да и не всегда возможно.)

Аутентификация на основе JWT (Json Web Tokens)

Состояние не отслеживается

JWT это строка следующего формата:

header.payload.signature

Например:

iLCJhbGciOiJIU.eyNjYwYmQifQ.5mb11y1537tM

Процедура аутентификации на основе токенов:

  1. Пользователь вводит имя и пароль.
  2. Сервер проверяет их и возвращает токен (JWT), который может содержать метаданные вроде user_id, разрешений и т. д.
  3. Токен хранится на клиентской стороне, чаще всего в локальном хранилище, но может лежать и в хранилище сессий или кук.
  4. Последующие запросы к серверу обычно содержат этот токен в качестве дополнительного заголовка авторизации в виде Bearer {JWT}. Ещё токен может пересылаться в теле POST-запроса и даже как параметр запроса.
  5. Сервер расшифровывает JWT, если токен верный, сервер обрабатывает запрос.
  6. Когда пользователь выходит из системы, токен на клиентской стороне уничтожается, с сервером взаимодействовать не нужно.

Аутентификация на основе токенов

Преимущества:

  • Серверу не нужно хранить записи с пользовательскими токенами или сессиями. Каждый токен самодостаточен, содержит все необходимые для проверки данные, а также передаёт затребованную пользовательскую информацию. Поэтому токены не усложняют масштабирование.
  • В куках вы просто храните ID пользовательских сессий, а JWT позволяет хранить метаданные любого типа, если это корректный JSON.
  • При использовании кук бэкенд должен выполнять поиск по традиционной SQL-базе или NoSQL-альтернативе, и обмен данными наверняка длится дольше, чем расшифровка токена. Кроме того, раз вы можете хранить внутри JWT дополнительные данные вроде пользовательских разрешений, то можете сэкономить и дополнительные обращения поисковые запросы на получение и обработку данных.
  • Допустим, у вас есть API-ресурс /api/orders, который возвращает последние созданные приложением заказы, но просматривать их могут только пользователи категории админов. Если вы используете куки, то, сделав запрос, вы генерируете одно обращение к базе данных для проверки сессии, ещё одно обращение — для получения пользовательских данных и проверки, относится ли пользователь к админам, и третье обращение — для получения данных.
  • А если вы применяете JWT, то можете хранить пользовательскую категорию уже в токене. Когда сервер запросит его и расшифрует, вы можете сделать одно обращение к базе данных, чтобы получить нужные заказы.
  • У использования кук на мобильных платформах есть много ограничений и особенностей. А токены сильно проще реализовать на iOS и Android. К тому же токены проще реализовать для приложений и сервисов интернета вещей, в которых не предусмотрено хранение кук.

Беспарольная аутентификация

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

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

Преимущество: нет необходиомсти реализовывать механизм восстановления паролей.

Аутентификация через единую точку входа (SSO)

Метод Single Sign On. Существуют различные реализации. Рассмотрим на примере Google Accounts. Когда логинишься в одном Google-сервисе, например Gmail, а потом получаешь доступ к остальным Google-сервисам без аутентификации, то ты пользуешься единую точку входа от Google. Удобно не правда ли? Процедура аутентификации на Google Accounts (SSO):

  1. Пользователь входит в один из сервисов Google.
  2. Пользователь получает сгенерированную в Google Accounts куку.
  3. Пользователь идёт в другой продукт Google.
  4. Пользователь снова перенаправляется в Google Accounts.
  5. Google Accounts видит, что пользователю уже присвоена кука, и перенаправляет пользователя в запрошенный продукт.

В этой процедуре используется три сущности:

  • user
  • identity provider
  • service provider

Пользователь вводит пароль (или аутентифицируется иначе) у поставщика идентификационной информации (identity provider, IDP), чтобы получить доступ к поставщику услуги (service provider (SP). Пользователь доверяет IDP, и SP доверяет IDP, так что SP может доверять пользователю.

Аутентификация с авторизация OAuth

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

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

Большинство соцсетей в качестве механизма аутентификации используют авторизацию через OAuth2.

Соцсеть — это сервер ресурсов, ваше приложение — клиент, а пытающийся войти в ваше приложение пользователь — владелец ресурса. Ресурсом называется пользовательский профиль / информация для аутентификации. Когда пользователь хочет войти в ваше приложение, оно перенаправляет пользователя в соцсеть для аутентификации (обычно это всплывающее окно с URL’ом соцсети). После успешной аутентификации пользователь должен дать вашему приложению разрешение на доступ к своему профилю из соцсети. Затем соцсеть возвращает пользователя обратно в ваше приложение, но уже с токеном доступа. В следующий раз приложение возьмёт этот токен и запросит у соцсети информацию из пользовательского профиля.

Для реализации такого механизма вам может понадобиться зарегистрировать своё приложение в разных соцсетях. Вам дадут app_id и другие ключи для конфигурирования подключения к соцсетям.

Двухфакторная аутентификация

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

Всем знаком следующий пример: сначалы вы вводите логин и пароль, а затем одноразовый пароль (код проверки), отправляемый вам по SMS. Если ваш обычный пароль был скомпрометирован, аккаунт останется защищённым, потому что на втором шаге входа злоумышленник не сможет ввести нужный код проверки.

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

При двухфакторной аутентификации пользователь должен предоставить два из трёх:

  • То, что вы знаете: пароль или PIN.
  • То, что у вас есть: физическое устройство (смартфон) или приложение, генерирующее одноразовые пароли.
  • Часть вас: биологически уникальное свойство вроде ваших отпечатков пальцев, голоса или снимка сетчатки.

Большинство хакеров охотятся за паролями и PIN-кодами. Гораздо труднее получить доступ к генератору токенов или биологическим свойствам, поэтому сегодня двухфакторная аутентификаия обеспечивает высокую безопасность аккаунтов.


По мотивам статьи на хабре Как ты реализуешь аутентификацию, приятель?