Веб-приложение без гражданства, городская легенда?

В наши дни я пытаюсь понять token-based authentication, который утверждает, что это метод stateless authentication. И я встретил концепцию stateless web application.

Ниже приведены несколько тем, о которых я читал:

Сначала я был в восторге от этой идеи. Но все больше и больше я думаю, что stateless - это pseudo-proposition.

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

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

Это зависит от того, как интерпретировать слово stateless:

  1. У веб-приложения нет состояния.
  2. Или веб-приложение не хранит состояние само.

Я предпочитаю 2, потому что всегда может быть inevitable global state (цитата из комментария @deceze к его ответу). И независимо от того, храним ли мы информацию о состоянии в виде веб-хранилища HTML 5, заголовка HTTP, скрытых полей формы или файла cookie, состояние все равно существует. Только то, что он хранится не на сервере.

Я что-то упустил? Может ли кто-нибудь пролить свет на это, чтобы избавить меня от этой душевной борьбы?

ДОБАВИТЬ 1

Просто прочтите о книге RESTful Web Services автора Leonard Richardson. В главе 4, в конце раздела Statelessness, он классифицирует состояние на Application State и Resource State. Таким образом, обычная информация о пользователе и данные, которые я упоминал ранее, такие как изображения и т. Д., Могут быть классифицированы как Resource State. И то, что stateless относится к Application State. Таким образом, он не нарушает код состояния без сохранения состояния для хранения resource state на сервере.

Но в книге также упоминается сценарий, в котором an application key is used to restrict how many times a user can invoke a web service. признается, что такая информация не может храниться на стороне клиента. И необходимость хранить его на стороне сервера нарушает код состояния без сохранения состояния и вызывает проблему сродства сеанса. В нем утверждается, что без сохранения состояния можно избежать проблемы сродства сеанса, но не объясняется, как это сделать. Я действительно не понимаю, как без состояния можно справиться с этим сценарием. Кто-нибудь мог пролить здесь свет?


person smwikipedia    schedule 08.01.2016    source источник
comment
Что такое веб-приложение без сохранения состояния? Откуда у вас этот термин? Я знаю только соединение / протокол без сохранения состояния.   -  person freakish    schedule 08.01.2016
comment
@freakish спасибо за ответ. Прочитал с нескольких веток. Я резюмировал несколько здесь: stackoverflow.com/questions/34651801/   -  person smwikipedia    schedule 08.01.2016
comment
Я думаю, что если вы напишете список недостатков statefull, вы сможете определить, каким должно быть stateless, верно? Но эти недостатки субъективны, поэтому четкого определения нет.   -  person Sergiu Paraschiv    schedule 08.01.2016
comment
И нет, ваш полный стек не будет иметь состояния, если вашим клиентам нужно состояние (Добро пожаловать, X, вы вошли в систему). сервер приложений может не иметь состояния, но ваш клиент этого не сделает, и, скорее всего, за сервером приложений также будет какое-то общее хранилище данных.   -  person Sergiu Paraschiv    schedule 08.01.2016
comment
@SergiuParaschiv Второй ваш комментарий - это именно то, что я думаю. Думаю, вы согласны с моей интерпретацией 2.   -  person smwikipedia    schedule 08.01.2016
comment
Да, я тоже так чувствую. Основная причина, по которой вам нужен сервер приложений без сохранения состояния, заключается в том, что обработка запросов изолирована, и вы можете аккуратно распределить их на нескольких машинах. Все они по-прежнему попадут в базу данных (которая может быть распределена сама по себе), но фактическая обработка запроса не зависит. Например, с сеансами это было бы невозможно - вам пришлось бы реплицировать данные сеанса на всех ваших машинах, обрабатывающих запросы.   -  person Sergiu Paraschiv    schedule 08.01.2016
comment
@SergiuParaschiv Бинго, ты снова меня ударил!   -  person smwikipedia    schedule 08.01.2016


Ответы (3)


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

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

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

Сравните это с аутентификацией на основе токенов. Токен должен быть действителен бессрочно. По сути, это замена имени пользователя и пароля. Для обсуждения просто предположим, что клиент отправляет свое имя пользователя и пароль с каждым запросом. Это означает, что каждый запрос может быть аутентифицирован сам по себе, не требуя, чтобы сервер находился в каком-то конкретном временном «состоянии».

Причина, по которой вы используете токены вместо имен пользователей и паролей, двоякая:

  1. вы можете авторизовать несколько клиентов, используя одну и ту же учетную запись, но каждый со своими индивидуально управляемыми учетными данными
  2. вы не хотите, чтобы "мастер-пароль" отправлялся туда и обратно при каждом запросе

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

Еще один потенциальный аргумент, который требует упреждающего противодействия: в чем разница между неопределенным сеансом и неопределенным токеном, и в чем разница, когда сеанс заканчивается и когда токен может быть отозван?
Когда сеанс заканчивается, его можно восстановить с использованием некоторых других «основных учетных данных» (повторный вход в систему). Токен может / должен заканчиваться только при активном аннулировании, что сродни отзыву авторизации для доступа к службе полностью для основных учетных данных и не является частью обычного потока приложений.


Говоря шире: сравните протокол HTTP без сохранения состояния с протоколом с отслеживанием состояния, таким как FTP. В FTP сервер и клиент должны синхронизировать общее состояние. Например, протокол FTP имеет, помимо прочего, команду CWD для изменения текущего рабочего каталога. То есть существует понятие о том, в каком каталоге находится клиент в любой момент времени. Последующие команды ведут себя по-разному в зависимости от того, в каком каталоге они находятся. Это состояние с отслеживанием состояния. Вы не можете произвольно отправлять команды, не зная об этом состоянии, иначе вы не сможете предсказать, каким будет результат.


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


С архитектурной точки зрения ваша цель должна состоять в том, чтобы иметь как можно больше компонентов без сохранения состояния. Это упростит горизонтальное масштабирование. Например, если ваш веб-сервер хранит локальное хранилище сеансов, это очень затрудняет масштабирование вашего веб-сервера на несколько экземпляров за балансировщиком нагрузки / CDN. Одним из улучшений является централизация хранилища сеансов в независимой базе данных; теперь у вас может быть несколько веб-серверов без сохранения состояния, которые знают, как откуда-то получать данные (включая данные сеанса) и могут отображать шаблоны, но в остальном полностью взаимозаменяемы.

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

person deceze♦    schedule 08.01.2016
comment
Спасибо за ответ. К настоящему времени, я думаю, есть некоторая неизбежная цена за масштабируемость. Отсутствие гражданства может только снизить цену, но не устранить ее. Если приложение разработано как не имеющее состояния (за исключением части токена), при масштабировании нужно позаботиться только о токенах, что намного проще, чем репликация временных данных сеанса. (кстати, я выделил часть вашего ответа). - person smwikipedia; 17.01.2016
comment
Правильно, любое глобальное состояние обычно является узким местом масштабируемости. Это означает, что хранилище данных должно быть глобально согласованным. Чем чаще данные в этом хранилище меняются, тем сложнее поддерживать их в актуальном состоянии во всех экземплярах. Следовательно, удалите как можно больше из этого, чтобы оставить как можно больше компонентов без состояния. - person deceze♦; 18.01.2016

Хорошо, я не думаю, что термин веб-приложение без сохранения состояния имеет смысл. Что действительно имеет смысл, так это протокол без сохранения состояния. А протокол без сохранения состояния - это тот, который обрабатывает каждый запрос независимо.

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

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

Протоколы без сохранения состояния легче масштабировать, проще прокси и т. Д.

Что касается веб-приложений, этот термин может иметь или не иметь смысла в зависимости от определения. Хотя я не знаю разумного.

Дополнительное примечание: состояние или отсутствие состояния не связано с обменом данными между клиентом и сервером.

person freakish    schedule 08.01.2016

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

Аутентификация без сохранения состояния - это метод идентификации клиента без передачи какой-либо информации / состояния из предыдущего запроса или взаимодействия с клиентом, в отличие, например, от файлов cookie.

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

person Boon    schedule 08.01.2016