Действительно ли сеансы нарушают спокойствие?

действительно ли использование сеансов в RESTful API нарушает спокойствие? Я видел много мнений, идущих в любом направлении, но я не уверен, что сессии неугомонный. С моей точки зрения:--5-->

  • аутентификация не запрещена для RESTfulness (в противном случае было бы мало пользы в RESTful services)
  • аутентификация выполняется путем отправки маркера аутентификации в запросе, обычно заголовка
  • этот маркер проверки подлинности необходимо как-то получить и может быть отозвано, в этом случае его необходимо обновить
  • маркер аутентификации должен быть проверен сервером (иначе это не была бы аутентификация)

Итак, как сеансы нарушают это?

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

таким образом, для клиента файл cookie сеанса точно такой же, как и любой другой механизм аутентификации на основе HTTP-заголовка, за исключением того, что он использует вместо Authorization или какой-либо другой проприетарный заголовок. Если на стороне сервера значений cookie не было сеанса, почему это имеет значение? Сторона сервера реализация не должна касаться клиента до тех пор, пока сервер поведение спокойный. Таким образом, cookies сами по себе не должны создавать API неугомонный, а сеансы - это просто cookies для клиента.

мои предположения ошибочны? Что делает сеанс cookies неугомонный?

6 ответов


во-первых, давайте определим некоторые термины:

  • RESTful:

    можно охарактеризовать приложения, соответствующие ограничениям REST описанные в этом разделе, как "спокойный".[15] если служба нарушает из требуемых ограничений его нельзя считать спокойным.

    по данным Википедия.

  • ограничение без гражданства:

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

    по словам Филдинг диссертация.

таким образом, сеансы на стороне сервера нарушают ограничение без состояния REST и поэтому RESTfulness.

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

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

на мой взгляд, нет ничего плохого в cookies. Технология cookie-это механизм хранения на стороне клиента, в котором сохраненные данные автоматически прикрепляются к заголовкам cookie по каждому запросу. Я не знаю ограничения на отдых. что имеет проблемы с такого рода технологией. Таким образом, нет проблем с самой технологией, проблема заключается в ее использовании. Филдинг написал подраздел о том, почему он считает http cookies плохими.

с моей точки зрения:

  • аутентификация не запрещена для RESTfulness (в противном случае было бы мало пользы в RESTful services)
  • аутентификация выполняется путем отправки маркера аутентификации в запросе, обычно заголовок
  • этот токен аутентификации должен быть получен каким-то образом и может быть отозван, и в этом случае он должен быть обновлен
  • маркер аутентификации должен быть проверен сервером (в противном случае это не была бы аутентификация)

ваша точка зрения была довольно твердой. Единственная проблема заключалась в концепции создания токена аутентификации на сервере. Тебе это не нужно. Вам нужно сохранить имя пользователя и пароль на клиенте и отправить его с каждым запросом. Вам не нужно больше, чтобы сделать это, чем HTTP basic auth и зашифрованное соединение:

Figure 1. - Stateless authentication by trusted clients

  • Рис. 1. - Аутентификация без состояния доверенными клиентами

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

теперь это работает довольно хорошо доверенными клиентами, написанными вами, но как насчет сторонних клиентов? Они не могут иметь имя пользователя и пароль и все разрешения пользователей. Таким образом, вы должны хранить отдельно, какие разрешения сторонний клиент может иметь определенным пользователем. Таким образом, клиентские разработчики могут зарегистрировать своих сторонних клиентов и получить уникальный ключ API, а пользователи могут разрешить сторонним клиентам доступ к некоторой части своих разрешений. Например, прочитать имя и адрес электронной почты,или перечислить своих друзей и т. д... После разрешения стороннему клиенту сервера будет генерировать токен доступа. Эти маркеры доступа могут использоваться сторонним клиентом для доступа к разрешениям, предоставленным пользователем, например:

Figure 2. - Stateless authentication by 3rd party clients

  • Рис. 2. - Аутентификация без гражданства сторонними клиентами

таким образом, сторонний клиент может получить маркер доступа от доверенного клиента (или непосредственно от пользователя). После этого он может отправить действительный запрос с ключом API и токеном доступа. Это самое основное Механизм auth третьей стороны. Вы можете узнать больше о деталях реализации в документации каждой сторонней системы аутентификации, например OAuth. Конечно, это может быть сложнее и безопаснее, например, вы можете подписать детали каждого отдельного запроса на стороне сервера и отправить подпись вместе с запросом и так далее... Реальное решение зависит от потребностей вашего приложения.


прежде всего, отдых не является религией и не должен рассматриваться как таковой. Хотя в услугах RESTful есть преимущества, вы должны следовать только принципам REST, насколько они имеют смысл для вашего приложения.

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

интернет Google услуги-фантастический пример системы RESTful. Они требуют, чтобы заголовок аутентификации с ключом аутентификации пользователя передавался по каждому запросу. Это немного нарушает принципы REST, поскольку сервер отслеживает состояние ключа проверки подлинности. Состояние этого ключа должно поддерживаться, и у него есть какая-то дата/время истечения срока действия, после которого он больше не предоставляет доступ. Однако, как я уже упоминал в верхней части моего поста, жертвы должны быть сделаны, чтобы разрешить применение фактически работать. Тем не менее, токены аутентификации должны храниться таким образом, чтобы все возможные клиенты могли продолжать предоставлять доступ в течение своего действительного времени. Если один сервер управляет состоянием ключа аутентификации до такой степени, что другой сервер с балансировкой нагрузки не может взять на себя выполнение запросов на основе этого ключа, вы начали действительно нарушать принципы REST. Сервисы Google гарантируют, что в любое время вы можете взять маркер аутентификации, который вы использовали на своем телефоне против сервера баланса нагрузки A и нажмите сервер баланса нагрузки B с рабочего стола и по-прежнему иметь доступ к системе и быть направлены на те же ресурсы, если запросы были идентичны.

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

Я надеюсь, что все это имело смысл. Вы должны также проверьте раздел ограничения на статья Википедии о передаче репрезентативного состояния если вы еще не. Это особенно поучительно в отношении того, о чем на самом деле спорят догматы покоя и почему.


Cookies не предназначены для аутентификации. Зачем изобретать колесо? HTTP имеет хорошо разработанные механизмы аутентификации. Если мы используем cookies, мы попадаем в использование HTTP только в качестве транспортного протокола, поэтому нам нужно создать наш собственные сигнальная система, например, чтобы сообщить пользователям, что они предоставили неправильную аутентификацию (использование HTTP 401 было бы неправильным, поскольку мы, вероятно, не предоставили бы Www-Authenticate клиенту, поскольку спецификации HTTP требуют :)). Следует также отметить, что Set-Cookie только a рекомендация для клиента. Его содержимое может быть сохранено или не сохранено (например, если cookies отключены), в то время как отправляется автоматически при каждом запросе.

другой момент заключается в том, что для получения файла cookie авторизации вы, вероятно, захотите сначала предоставить свои учетные данные? Если так, то не будет ли оно беспокойным? Простой пример:

  • ты попробуй GET /a без печенья
  • вы получаете запрос на авторизацию как-нибудь!--16-->
  • вы идете и разрешаете как-то вроде POST /auth
  • вы получаете Set-Cookie
  • ты попробуй GET /a С cookie. Но GET /a вести себя идемпотентно в этом случае?

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


на самом деле, RESTfulness применяется только к ресурсам, как указано универсальным идентификатором ресурса. Поэтому даже говорить о таких вещах, как заголовки, куки и т. д. в отношении отдыха это не совсем уместно. REST может работать над любым протоколом, даже если это обычно делается через HTTP.

основной определитель таков: если вы отправляете вызов REST, который является URI, то после того, как вызов делает его успешно на сервер, этот URI возвращает тот же контент, предполагая, что нет были ли выполнены переходы (PUT, POST, DELETE)? Этот тест исключил бы ошибки или запросы аутентификации, возвращаемые, потому что в этом случае запрос еще не сделал его на сервер, то есть сервлет или приложение, которое возвратит документ, соответствующий данному URI.

аналогично, в случае POST или PUT, вы можете отправить данный URI / полезную нагрузку, и независимо от того, сколько раз вы отправляете сообщение, он всегда будет обновлять те же данные, так что последующие GETs вернет согласованный результат?

REST-это данные приложения, а не информация низкого уровня, необходимая для передачи этих данных.

в следующем сообщении в блоге Рой Филдинг дал хорошее резюме всей идеи отдыха:

http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841

"система RESTful прогрессирует от одного стационарного состояния к далее, и каждый такой стационарный оба потенциальных start-state и потенциальное конечное состояние. То есть, система RESTful неизвестна количество компонентов, подчиняющихся простому набору правил, так что они всегда или в покое или переходя от одного RESTful состояние в другое спокойное состояние. Каждое состояние может быть полностью понимается представление(ы), которое оно содержит и множество переходы, которые он предоставляет, с переходами, ограниченными a единый набор действий должен быть понятен. Система может быть сложная диаграмма состояний, но каждый агент пользователя может видеть только одно состояние за раз (текущее устойчивое состояние) и, таким образом, каждый состояние простое и может анализироваться независимо. Пользователь, OTOH, способен создавать собственные переходы в любое время (например, введите URL-адрес, выберите закладку, откройте редактор и т. д.)."


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

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

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


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

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

Так что проблема не может быть решена с помощью обычной проверки подлинности.

чтобы решить эту проблему, необходимо поддерживать сеанс, и это, по некоторым ответам, противоречит покою.

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

для меня не так много способов поддерживать сеанс через HTTP. Можно использовать cookies с sessionId или заголовок с sessionId.

Если у кого то есть еще идеи буду рад услышать он.


  1. сеансы не беспокойные
  2. вы имеете в виду, что служба REST для http-использования только или я ошибся? Cookie-сессии должны использоваться только для собственных (!) http-сервисы! (Это может быть проблемой для работы с cookie, например с мобильного телефона/консоли/стола/и т. д.)
  3. Если вы предоставляете услугу RESTful для разработчиков 3d-партий, никогда не используйте сеанс на основе файлов cookie, используйте токены, чтобы избежать проблем с безопасностью.