Я нуждаюсь в некоторых разъяснениях. Я читал о REST и создании приложений RESTful. Согласно википедии, сам REST определен как представительский государственный трансферт . Поэтому я не понимаю всех этих бездарных гоблидов, которые все продолжают извергать.
Из википедии:
В любой конкретный момент клиент может переходить между состояниями приложения или находиться в состоянии покоя. Клиент в состоянии покоя может взаимодействовать со своим пользователем, но не создает нагрузки и не использует хранилище для каждого клиента на наборе серверов или в сети.
Они просто говорят, что не используют хранилище данных на уровне сеанса / приложения ???
Я понял, что одна из целей REST - сделать доступ к URI согласованным и доступным, например, вместо того, чтобы скрывать запросы подкачки внутри постов, делая номер страницы запроса частью GET URI. Имеет смысл для меня. Но кажется, что это просто зашкаливает, говоря, что никакие данные для каждого клиента (данные сеанса) никогда не должны храниться на стороне сервера.
Что если бы у меня была очередь сообщений, и мой пользователь хотел прочитать сообщения, но, читая их, хотел заблокировать поступающие сообщения определенных отправителей на время его сеанса? Разве не имеет смысла хранить это в месте на стороне сервера, и сервер должен только отправлять сообщения (или идентификаторы сообщений), которые не были заблокированы пользователем?
Нужно ли отправлять полный список отправителей сообщений каждый раз, когда я запрашиваю новый список сообщений? Список сообщений, относящихся ко мне, не будет / даже не должен быть общедоступным ресурсом.
Опять же, просто пытаюсь понять это. Кто-то, пожалуйста, уточните .
Обновить:
Я нашел вопрос переполнения стека, на который есть ответ, который мне не совсем понятен: как управлять состоянием в REST, в котором говорится, что важное состояние клиента должно передаваться при каждом запросе .... Ugg .. похоже, много накладных расходов ... Это правильно ??
Ответы:
Отсутствие состояния означает, что каждый HTTP-запрос происходит в полной изоляции. Когда клиент делает HTTP-запрос, он включает всю информацию, необходимую серверу для выполнения этого запроса. Сервер никогда не полагается на информацию из предыдущих запросов. Если эта информация важна, клиент должен будет отправить ее снова в последующем запросе. Безгражданство также приносит новые возможности. Проще распределить приложение без сохранения состояния между серверами с балансировкой нагрузки. Приложение без сохранения состояния также легко кэшируется.
На самом деле существует два вида государства. Состояние приложения, которое живет на клиенте, и состояние ресурса, которое живет на сервере.
Веб-сервису нужно заботиться о состоянии вашего приложения только тогда, когда вы действительно делаете запрос. В остальное время он даже не знает, что вы существуете. Это означает, что всякий раз, когда клиент делает запрос, он должен включать все состояния приложения, которые будут необходимы серверу для его обработки.
Состояние ресурса одинаково для каждого клиента, и его правильное место на сервере. Когда вы загружаете изображение на сервер, вы создаете новый ресурс: новое изображение имеет свой собственный URI и может быть целью будущих запросов. Вы можете получить, изменить и удалить этот ресурс через HTTP.
Надеюсь, что это помогает дифференцировать то, что означает безгражданство и различные состояния.
источник
Основное объяснение:
Без сохранения состояния это означает, что сервер не хранит никакого состояния о сеансе клиента на стороне сервера.
Сеанс клиента хранится на клиенте. Сервер без гражданства означает , что каждый сервер может обслуживать любой клиент в любое время, нет сродства сеанса или липких сессий . Соответствующая информация о сеансе сохраняется на клиенте и передается на сервер по мере необходимости.
Это не мешает другим службам, с которыми общается веб-сервер, поддерживать состояние о бизнес-объектах, таких как корзины покупок, но не о текущем состоянии приложения / сеанса клиента.
Состояние приложения клиента никогда не должно храниться на сервере, а должно передаваться от клиента во все места, где это необходимо.
Вот откуда происходит ST в REST , State Transfer . Вы передаете состояние вместо того, чтобы сервер сохранял его. Это единственный способ масштабирования до миллионов одновременно работающих пользователей. Если ни по какой другой причине, кроме как потому, что миллионы сеансов - это миллионы сеансов.
Нагрузка на управление сеансом амортизируется для всех клиентов, клиенты сохраняют свое состояние сеанса, и серверы могут обслуживать многие заказы или более клиентов без сохранения состояния.
Даже для службы, которая, по вашему мнению, понадобится только десяткам тысяч одновременно работающих пользователей, вы все равно должны сделать свою службу не имеющей состояния. Десятки тысяч - это еще десятки тысяч, и с этим будут связаны затраты времени и пространства.
Stateless - это то, как протокол HTTP и сеть в целом были разработаны для работы, и это в целом более простая реализация, и у вас есть один путь к коду вместо набора логики на стороне сервера для поддержания группы состояний сеанса.
Есть несколько очень простых принципов реализации:
Это принципы, а не реализации, то, как вы соблюдаете эти принципы, может отличаться.
Таким образом, пять ключевых принципов :
В диссертации REST ничего не говорится об аутентификации или авторизации .
Потому что ничто не отличается от аутентификации запроса, который является RESTful, от запроса, который не является. Аутентификация не имеет отношения к обсуждению RESTful.
Объяснять, как создать приложение без сохранения состояния для ваших конкретных требований, слишком сложно для StackOverflow.
Реализация аутентификации и авторизации в части, касающейся REST, еще более обширна, и различные подходы к реализации подробно описаны в Интернете в целом.
источник
Нет, они не говорят это тривиальным образом.
Они говорят, что не определяют «сессию». Не входите Не выходите из системы. Предоставьте учетные данные вместе с запросом. Каждый запрос стоит отдельно.
У вас все еще есть хранилища данных. У вас все еще есть аутентификация и авторизация. Вы просто не тратите время на установление сеансов и поддержание состояния сеанса.
Дело в том, что каждый запрос (а) стоит совершенно один и (б) может быть тривиально перенесен в гигантскую параллельную ферму серверов без какой-либо реальной работы. Apache или Squid могут передавать запросы RESTful вслепую и успешно.
Если пользователь хочет фильтр, то просто предоставьте фильтр для каждого запроса.
Да. Укажите фильтр в запросе RESTful URI.
Да. Насколько большим может быть этот «список отправителей сообщений для блокировки»? Краткий список ПК?
Запрос GET может быть очень большим. При необходимости вы можете попробовать запрос POST, даже если он звучит как запрос.
источник
Вы абсолютно правы, поддержка взаимодействия с сервером без сохранения состояния создает дополнительную нагрузку на клиента. Однако, если вы подумаете о масштабировании приложения, вычислительная мощность клиентов прямо пропорциональна количеству клиентов. Поэтому масштабирование на большое количество клиентов гораздо более осуществимо.
Как только вы возлагаете небольшую ответственность на сервер за управление некоторой информацией, относящейся к взаимодействиям конкретного клиента, эта нагрузка может быстро возрасти и потреблять сервер.
Это компромисс.
источник
Исторический обзор управления состоянием пользовательских приложений
Сеансы в традиционном смысле сохраняют состояние пользователя в приложении внутри сервера. Это может быть текущая страница в потоке или то, что было ранее введено, но еще не сохранено в основной базе данных.
Причиной такой необходимости было отсутствие стандартов на стороне клиента для эффективного поддержания состояния без создания специфичных для клиента (т. Е. Для браузера) приложений или плагинов.
HTML5 и XML Header Request со временем стандартизировали понятие хранения сложных данных, включая состояние приложения, стандартным способом на стороне клиента (т.е. браузера), не прибегая к переходу назад и вперед между сервером.
Общее использование услуг REST
Службы REST обычно вызываются, когда есть транзакция, которая должна быть выполнена, или если ей нужно получить данные.
Службы REST предназначены для вызова клиентским приложением, а не конечным пользователем напрямую.
Проверка подлинности
Для любого запроса к серверу часть запроса должна содержать токен авторизации. Как это реализовано, зависит от конкретного приложения, но в целом это либо форма проверки подлинности,
BASIC
либоCERTIFICATE
форма.Проверка подлинности на основе форм не используется службами REST. Однако, как отмечено выше, службы REST предназначены не для вызова пользователем, а для приложения. Приложение должно управлять получением токена аутентификации. В моем случае я использовал куки с JASPIC с OAuth 2.0 для подключения к Google для аутентификации и простой HTTP-аутентификации для автоматического тестирования. Я также использовал аутентификацию HTTP-заголовка через JASPIC для локального тестирования (хотя такой же подход может быть выполнен в SiteMinder)
Согласно этим примерам, аутентификация управляется на стороне клиента (хотя SiteMinder или Google будут хранить сеанс аутентификации на их конце), с этим состоянием ничего нельзя поделать, но оно не является частью приложения-службы REST.
Поисковые запросы
Запросы на получение в REST - это
GET
операции, при которых конкретный ресурс запрашивается и кэшируется. Нет необходимости в сеансах сервера, потому что в запросе есть все, что нужно для извлечения данных: аутентификация и URI.Сценарии транзакций
Как отмечено выше, клиентское приложение само вызывает службы REST вместе с аутентификацией, которой оно также управляет на стороне клиента.
Для сервисов REST [если все сделано правильно] это означает, что один запрос к серверу REST будет содержать все, что нужно для однопользовательской операции, которая выполняет все, что нужно в одной транзакции, а сценарий транзакции - это то, что шаблон называется.
POST
Обычно это делается с помощью запроса, ноPUT
также могут использоваться и другие.Многие надуманные примеры REST (я сам делал это) пытались следовать как можно большему количеству того, что было определено в протоколе HTTP, после того как я решил стать более прагматичным и оставил это только GET и POST .
POST
Метод даже не должен реализовать шаблон POST-Redirect-GET.Несмотря на это, как я уже отмечал выше, клиентское приложение будет тем, которое вызывает службу, и будет вызывать
POST
запрос со всеми данными только тогда, когда это необходимо (не каждый раз). Это предотвращает постоянные запросы к серверу.голосование
Хотя REST также можно использовать для опроса, я не буду рекомендовать его, если вы не будете использовать его из-за совместимости браузера. Для этого я бы использовал WebSockets, для которых я также разработал контракт API . Другой альтернативой для старых браузеров является CometD.
источник
ОТДЫХ очень абстрактный. Это помогает иметь несколько хороших, простых, реальных примеров.
Возьмем, к примеру, все основные приложения для социальных сетей - Tumblr, Instagram, Facebook и Twitter. Все они имеют вид с непрерывной прокруткой, где чем дальше вы прокручиваете, тем больше контента вы видите, все дальше и дальше назад во времени. Тем не менее, мы все пережили тот момент, когда вы теряете то, куда вас прокручивали, и приложение сбрасывает вас обратно наверх. Например, если вы выйдете из приложения, то при повторном открытии вы снова вернетесь наверх.
Причина в том, что сервер не сохранил ваше состояние сеанса. К сожалению, ваша позиция прокрутки была просто сохранена в RAM на клиенте.
К счастью, вам не нужно повторно входить в систему при повторном подключении, но это только потому, что срок хранения вашего сертификата входа на стороне клиента также не истек. Удалите и переустановите приложение, и вам придется снова войти в систему, поскольку сервер не связал ваш IP-адрес с вашим сеансом.
У вас нет сеанса входа на сервер, потому что они соблюдают REST.
Теперь в приведенных выше примерах вообще не используется веб-браузер, но на заднем плане приложения обмениваются данными через HTTPS со своими хост-серверами. Я хочу сказать, что REST не должен включать файлы cookie, браузеры и т. Д. Существуют различные способы хранения состояния сеанса на стороне клиента.
Но давайте поговорим о веб-браузерах на секунду, потому что это поднимает еще одно важное преимущество REST, о котором никто здесь не говорит.
Если сервер пытался сохранить состояние сеанса, как он должен идентифицировать каждого отдельного клиента?
Он не может использовать свой IP-адрес, потому что многие люди могут использовать этот же адрес на общем маршрутизаторе. Так как же тогда?
Он не может использовать MAC-адрес по многим причинам, не в последнюю очередь из-за того, что вы можете войти в несколько учетных записей Facebook одновременно в разных браузерах и в приложении. Один браузер может легко выдать себя за другой, а MAC-адреса также легко подделать.
Если сервер должен хранить какое-то состояние на стороне клиента, чтобы идентифицировать вас, он должен хранить его в ОЗУ дольше, чем просто время, необходимое для обработки ваших запросов, иначе ему придется кэшировать эти данные. Серверы имеют ограниченный объем оперативной памяти и кеша, не говоря уже о скорости процессора. Состояние на стороне сервера добавляет ко всем трем экспоненциально. Кроме того, если сервер собирается хранить какие-либо данные о ваших сеансах, он должен хранить их отдельно для каждого браузера и приложения, в которых вы вошли в данный момент, а также для каждого другого используемого вами устройства.
Итак ... я надеюсь, что вы теперь понимаете, почему REST так важен для масштабируемости. Я надеюсь, что вы начнете понимать, почему состояние сеанса на стороне сервера связано с масштабируемостью сервера, а наковальни - с ускорением автомобиля.
Люди запутываются, думая, что «состояние» относится, например, к информации, хранящейся в базе данных. Нет, это относится к любой информации, которая должна быть в оперативной памяти сервера, когда вы ее используете.
источник
Я вижу, что основной проблемой здесь является смешение сессии с государством . И хотя REST указывает, что вы НЕ должны хранить состояние на сервере, ничто не мешает вам сохранить пользовательский сеанс .
Управление состоянием на сервере означает, что ваш сервер точно знает, что делает клиент (какую страницу они просматривают в каком разделе приложения). И это то, что вам не нужно делать.
Я согласен с другими людьми, которые говорят, что вы должны сохранить размер хранилища сессии до минимального размера; и хотя это здравый смысл, на самом деле это также зависит от приложения. Итак, короче говоря, вы все еще можете поддерживать сеанс с кэшированными данными для обработки запросов с меньшей нагрузкой на сервер и управлять аутентификацией, предоставляя клиенту временный токен аутентификации / доступа. Когда истекает срок сеанса / токена, генерируйте новый и просите клиента использовать его.
Кто-то может поспорить, что клиент должен лучше генерировать токен. Я говорю, что это работает в обоих направлениях, и это будет зависеть от приложения и от того, кто будет работать с API.
Также следует хранить некоторые конфиденциальные данные сеанса на сервере. Вы не можете доверять клиенту хранить его корзину покупок, которая (например) содержит поле с именем «isFreeGift». Такая информация должна храниться на сервере.
Ссылка на видео, предоставленная Сантану Дей в его ответе, полезна. Посмотрите, если нет.
Просто примечание: кажется, что все уже приведенные ответы игнорируют тот факт, что некоторые операции могут вызвать большую нагрузку на сервер. Это актуально с точки зрения энергопотребления, потребления оборудования и стоимости (для серверов, арендуемых по циклу ЦП). Хороший разработчик не должен лениться оптимизировать свое приложение, даже если операция может быть выполнена очень быстро на современном процессоре на некотором арендованном сервере, за который они не оплачивают счета за электроэнергию и техническое обслуживание.
Хотя этому вопросу уже несколько лет, я надеюсь, что мой ответ все равно будет полезен.
источник
Взято с http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap
источник
Здесь нет ложки.
Не думайте о безгражданстве, как "отправлять все свои вещи на сервер снова и снова". Ни за что. Всегда будет состояние - ведь сама база данных является своего рода состоянием, вы - зарегистрированный пользователь, поэтому любой набор информации на стороне клиента не будет действительным без стороны сервера. Технически, ты никогда не будешь по- настоящему без гражданства.
Слово в логине каждый раз, когда дебаты
Что вообще значит не вести сеанс и не входить каждый раз? Некоторые означают «отправлять пароль каждый раз», это просто глупо. Некоторые говорят: «Нет, конечно, нет, вместо этого отправьте токен » - и вот, PHP-сессия делает это почти точно. Он отправляет идентификатор сеанса, который является своего рода токеном, и помогает вам получить доступ к вашим личным материалам без повторной отправки u / pw каждый раз. Это также довольно надежно и хорошо проверено. И да, удобно, что может превратиться в недостаток, см. Следующий абзац.
Уменьшить след
Вместо этого вам следует сделать то , что имеет реальный смысл, - сократить до минимума площадь вашего веб-сервера. Такие языки, как PHP, очень просто помещают все в хранилище сессий, но у сессий есть свой ценник. Если у вас есть несколько веб-серверов, им нужно делиться информацией о сеансе, потому что они тоже распределяют нагрузку - любой из них, возможно, должен будет обслуживать следующий запрос.
Общее хранилище является обязательным. Сервер должен знать, по крайней мере, кто-то вошел в систему или нет. (И если вы беспокоитесь о базе данных каждый раз, когда вам нужно решить это, вы практически обречены.) Общие хранилища должны быть намного быстрее, чем база данных. Это приносит соблазн: хорошо, у меня очень быстрое хранилище, почему бы не сделать все там? - и вот где все идет не так, как надо.
То есть вы говорите, что хранилище сессий должно быть минимальным?
Опять же, это ваше решение. Вы можете хранить вещи там из соображений производительности (база данных почти всегда медленнее, чем Redis), вы можете хранить информацию избыточно, реализовывать собственное кэширование, что угодно - просто имейте в виду, что веб-серверы будут иметь большую нагрузку, если вы будете хранить много мусора на них. Кроме того, если они сломаются под большими нагрузками (и они будут), вы потеряете ценную информацию; При REST-способе мышления все, что происходит в этом случае, это то, что клиент снова отправляет тот же (!) запрос, и на этот раз он обслуживается.
Как это сделать правильно тогда?
Здесь нет универсального решения. Я бы сказал, выбрать уровень безгражданства и пойти с этим. Одни сеансы могут быть любимыми и ненавистными для других, но они никуда не денутся. С каждым запросом отправляйте столько информации, сколько имеет смысл, возможно, чуть больше; но не интерпретируйте безгражданство как отсутствие сеанса или вход в систему каждый раз. Каким-то образом сервер должен знать, что это вы ; Идентификаторы сессий PHP - один хороший способ, токены, созданные вручную, другой.
Думайте и решайте, не позволяйте тенденциям дизайна думать за вас.
источник
Посмотрите на эту презентацию.
http://youtu.be/MRxTP-rQ-S8
Согласно этому шаблону - создайте временные спокойные ресурсы для управления состоянием, если и когда это действительно необходимо. Избегайте явных сессий.
источник
Основное различие между сохранением состояния и сохранением состояния заключается в том, что данные каждый раз передаются обратно на сервер. В случае отсутствия состояния клиент должен предоставить всю информацию, поэтому в каждом запросе может потребоваться передача большого количества параметров. В Stateful клиент передает эти параметры один раз, и они поддерживаются сервером, пока клиент снова не изменит их.
ИМО, API должен быть без сохранения состояния, что позволяет действительно быстро масштабироваться.
источник
Вы должны управлять сеансом клиента на стороне клиента. Это означает, что вы должны отправлять данные аутентификации с каждым запросом, и у вас, вероятно, но не обязательно, есть кэш в памяти на сервере, который связывает данные аутентификации с пользовательской информацией, такой как личность, разрешения и т. Д.
Это ограничение на безгражданство REST очень важно. Без применения этого ограничения ваше серверное приложение не будет хорошо масштабироваться , потому что поддержка каждого отдельного сеанса клиента будет его ахиллесовой пятой .
источник
Когда вы разрабатываете службу RESTful, для входа в систему вам потребуется аутентификация вашего пользователя. Возможный вариант - отправлять имя пользователя и пароль каждый раз, когда вы собираетесь выполнить действие пользователя. В этом случае сервер вообще не будет хранить данные сеанса.
Другим вариантом является создание идентификатора сеанса на сервере и отправка его клиенту, чтобы клиент мог отправить идентификатор сеанса на сервер и выполнить аутентификацию с этим. Это намного безопаснее, чем отправлять имя пользователя и пароль каждый раз, поскольку, если кто-то получит свои данные, он может выдать себя за пользователя до тех пор, пока имя пользователя и пароль не будут изменены. Вы можете сказать, что даже идентификатор сессии может быть украден, и в этом случае пользователь будет выдавать себя за другого, и вы правы. Однако в этом случае олицетворение пользователя будет возможно только при действительном идентификаторе сеанса.
Если RESTful API ожидает имя пользователя и пароль для изменения имени пользователя и пароля, то даже если кто-то выдал себя за пользователя, используя идентификатор сеанса, хакер не сможет заблокировать реального пользователя.
Идентификатор сеанса может быть сгенерирован путем односторонней блокировки (шифрования) чего-то, что идентифицирует пользователя и добавляет время к идентификатору сеанса, таким образом, можно определить время истечения сеанса.
Сервер может хранить или не хранить идентификаторы сеансов. Конечно, если сервер хранит идентификатор сеанса, он будет нарушать критерии, определенные в вопросе. Однако важно только убедиться, что идентификатор сеанса может быть проверен для данного пользователя, что не требует сохранения идентификатора сеанса. Представьте себе способ одностороннего шифрования электронной почты, идентификатора пользователя и некоторых личных данных пользователя, таких как любимый цвет, это будет первый уровень и каким-то образом добавление даты имени пользователя в зашифрованную строку и применение двухстороннего способ шифрования. В результате, когда идентификатор сеанса получен, второй уровень может быть дешифрован, чтобы иметь возможность определить, какое имя пользователя утверждает, что пользователь является и правильное ли время сеанса. Если это действительно, затем можно проверить первый уровень шифрования, снова выполнив это шифрование и проверив, соответствует ли оно строке. Вам не нужно хранить данные сеанса, чтобы достичь этого.
источник
Вся концепция в другом ... Вам не нужно управлять сессиями, если вы пытаетесь реализовать протокол RESTFul. В этом случае лучше выполнять процедуру аутентификации для каждого запроса (в то время как с точки зрения производительности это требует дополнительных затрат - хорошим примером может служить хеширование пароля. Ничего страшного ...). Если вы используете сеансы - как вы можете распределить нагрузку между несколькими серверами? Бьюсь об заклад, протокол RESTFul предназначен для исключения сессий вообще - они вам на самом деле не нужны ... Вот почему он называется «без сохранения состояния». Сеансы требуются только в том случае, если вы не можете сохранить что-либо, кроме Cookie, на стороне клиента после выполнения запроса (например, старый браузер, не поддерживающий Javascript / HTML5). В случае «полнофункционального» клиента RESTFul его обычно безопасно хранить
base64(login:password)
на стороне клиента (в памяти) до тех пор, пока приложение не будет загружено - приложение используется для доступа к единственному хосту, и cookie не может быть скомпрометирован сторонними сценариями ...Я настоятельно рекомендую отключить проверку подлинности с помощью cookie-файлов для сервисов RESTFul ... проверьте Basic / Digest Auth - этого должно быть достаточно для сервисов на основе RESTFul.
источник
a client side (in memory)
и как безопасно хранитьbase64(login:password)
на стороне клиента?REST не имеет состояния и не поддерживает состояния между запросами. Клиентские куки / заголовки настроены на поддержание пользовательского состояния, такого как аутентификация. Скажем, имя пользователя / пароль клиента проверяются механизмом аутентификации третьей стороны - получение OTP 2-го уровня и т. Д. Как только пользователь проходит аутентификацию - заголовки / файлы cookie доходят до конечной точки службы покоя, и мы можем считать пользователя аутентифицированным, поскольку пользователь приходит с действительными заголовками / файлами cookie. , Теперь определенная информация о пользователе, например IP, либо сохраняется в кэше, и после этого, если запрос поступает с того же Ip (mac-адреса) для перечисленных ресурсов, пользователю разрешено. И кеш поддерживается некоторое время, которое становится недействительным по прошествии времени. Таким образом, можно использовать либо кэш, либо записи БД для сохранения информации в ч / б запросах.
источник
Состояние без сохранения здесь означает, что состояние или метаданные запроса не поддерживаются на стороне сервера. Поддержание каждого запроса или состояния пользователя на сервере может привести к узким местам производительности. Сервер просто запрашивается с необходимыми атрибутами для выполнения каких-либо конкретных операций.
Приходя к управлению сессиями или предоставляя пользователям настраиваемый опыт, требуется поддерживать некоторые метаданные или состояние вероятных пользовательских предпочтений пользователя, историю прошлых запросов. Это может быть сделано путем сохранения файлов cookie, скрытых атрибутов или объекта сеанса.
Это может поддерживать или отслеживать состояние пользователя в приложении.
Надеюсь это поможет!
источник