Идентификация пользователей в Web 3.0

В данной статье я публикую свои размышления по поводу идентификации пользователей в плавно привходящей третьей версии веба — Web 3.0. Если коротко, то, в отличие от стремящегося к гипер-централизации Web 2.0 (в пределе — по одному веб-приложению разного типа на всё человечество с центром у какой-нибудь глобальной корпорации), Web 3.0 отличается как раз таки децентрализацией и повышенным вниманием к конфиденциальности пользовательских данных (хотя ничего не мешает тем же глобальным корпорациям контролировать функциональность этих децентрализованных приложений на уровне кода приложения или среды его выполнения — браузера или ОС).

2.0 vs 3.0: децентрализация и конфиденциальность

2.0 vs 3.0: децентрализация и конфиденциальность

Так какие же требования к идентификации могут предъявлять веб-приложения современного настоящего и ближайшего будущего?

UUID

Децентрализованный характер v3-приложений диктует использование UUID в качестве базы для идентификации чего угодно:

c2115ec9-dade-4475-be27-55c7f7b03db8

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

userUuid

Понятно, что каждому пользователю должен соответствовать его собственный userUuid, генерируемый клиентским ПО (фронтом) в момент регистрации пользователя в v3-приложении. Идентификаторы типа nickname, login, email, phone в v3-приложениях использоваться не будут.

hostUuid

Веб-приложения, использующие в качестве фронта браузер (SPA, PWA), просто обязаны иметь некий сервер, с которого подгружается код клиентской части (хост-сервер). Возможность работы PWA в режиме offline диктует необходимость иметь некий «почтовый ящик» (очередь сообщений), в котором могут хранится сообщения других пользователей для данного пользователя, пока он не «выйдет из сумрака» (станет online). Очевидно, что данный «почтовый ящик» будет находиться на хост-сервере.

Хосты и клиенты

Хосты и клиенты

Более того, даже для не-браузерных клиентов должен быть такой же, всегда доступный, «почтовый ящик» с постоянным адресом, из которого пользователь будет забирать приходящие к нему сообщения. Просто в силу того, что основным устройством для выхода в интернет всё чаще становится мобильный телефон и тут ни о каком постоянном ip-адресе речь идти не может в принципе.

Итого: идентификация пользователя в приложениях Web 3.0 будет иметь примерно такой вид (порядок частей и разделитель не важен):

// userUuid:hostUuid
c2115ec9-dade-4475-be27-55c7f7b03db8:31f806ab-8ddc-4397-a1ab-ad5f9fe8f55f

Нам (разрабам) нужно будет не только знать идентификатор самого пользователя, но также и идентификатор его хост-сервера.

Ключи шифрования

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

Ключи шифрования

Ключи шифрования

Таким образом, чтобы отправить сообщение какому-либо пользователю в v3-приложении, помимо его userUuid:serverUuid нужно будет знать также и публичный ключ (pubKey) получателя сообщения. Очень похоже, что хост-сервер будет хранить все идентификаторы зарегистрировавшихся на нём пользователей и их публичные ключи, чтобы любой другой пользователь мог оставить конфиденциальное «почтовое сообщение» хостящимся на сервере пользователям.

frontUuid

В общем случае пользователь может подключаться к серверу при помощи совершенно разных клиентов (SPA в браузере, PWA в браузере/мобильном, нативные мобильные приложения для iOS и Android).

Множественные клиенты (фронты)

Множественные клиенты (фронты)

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

Хранение данных

Децентрализация и требования конфиденциальности приводит к тому, что в качестве основного хранилища используются ресурсы клиента, а не сервера (localStorage, IndexedDB, file-system, cloud):

Хранение данных пользователя

Хранение данных пользователя

Уже сейчас рядовой пользователь имеет в своём мобильном телефоне больше пространства, чем даёт тот же Gmail (Web 2.0) по-умолчанию (15 Гб).

Если v3-приложение позволяет пользователю подключаться с разных фронтов, а основным хранилищем для данных пользователя являются хранилища фронта (например, IndexedDB), то возникает необходимость репликации данных между фронтами. Репликация может проходить как через хранилище бэка, так и через внешнее хранилище (например, облако), и даже напрямую (peer-to-peer):

Варианты репликации данных между фронтами

Варианты репликации данных между фронтами

Если данные пользователя реплицируются через облако (или есть возможность экспорта/импорта данных), то у пользователя появляется возможность достаточно просто сменить не только свой хост, но и свой идентификатор в v3-приложении. Разумеется, это повлечёт за собой необходимость оповещения своих контрагентов (как минимум, нужных) о смене идентификаторов.

Токен доступа

Обычно в веб-приложениях процесс идентификации пользователя неразрывно связан с его аутентификацией (по паролю, биометрии, внешнему устройству). В результате процесса аутентификации сервер выдаёт некий токен (JWT, session cookies, …) по которому в дальнейшем и происходит идентификация и авторизация пользователя.

Этот токен привязывается к пользователю и к фронту, через который пользователь аутентифицировался.

Пароль пользователя

Несмотря на прогресс в области аутентификации (биометрия, внешние программные и аппаратные устройства) пароль, хранящийся в голове пользователя, до сих пор является, возможно, самым надёжным способом аутентификации персон. Так как все данные хранятся на клиенте, включая приватный ключ для подписи и дешифрирования сообщений, и могут экспортироваться/импортироваться на внешний носитель, то есть ненулевая вероятность утечки критических данных. В этом случае появляется необходимость пересоздать ключи шифрования, а возможно и сам идентификатор (userUuid). Пароль пользователя является классическим способом подтверждения аутентичности и вряд ли исчезнет из веб-приложений в ближайшем будущем.

sessionUuid

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

В таких приложениях сервер должен различать не только пользователей и фронты, с которых пользователь подключается к серверу, но также и вкладки, на которые нужно «лить» те или иные данные. В браузере есть хранилище данных, которое не разделяется между вкладками — sessionStorage, в отличие от localStorage. Таким образом, в некоторых случаях серверу помимо frontUuid нужно знать также и sessionUuid.

Резюме

В общем случае в децентрализованных приложениях Web 3.0 разработчикам необходимо идентифицировать следующие сущности:

  • пользователь (userUuid)

  • «домашний» сервер пользователя (hostUuid)

  • клиентское приложение пользователя (frontUuid)

  • вкладка браузера (sessionUuid)

Так как круглосуточная (24×7) передача данных в режиме peer-to-peer между пользователями v3-приложений невозможна, то возникает необходимость в использовании ассиметричного шифрования для хранения сообщений в очереди сообщений на «домашнем» сервере получателя. Как следствие, пользователи также должны будут обмениваться своими публичными ключами.

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

© Habrahabr.ru