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

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

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

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

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

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

Я ошибаюсь в своих предположениях? Что делает cookie сеанса RESTless?

Ответ 1

Сначала определим некоторые термины:

  • RESTful:

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

    в соответствии с wikipedia.

  • Ограничение без сохранения:

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

    согласно Филдинг-диссертация.

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

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

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

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

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

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

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

Figure 1. - Stateless authentication by trusted clients

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

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

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

Figure 2. - Stateless authentication by 3rd party clients

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

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

Ответ 2

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

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

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

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

Надеюсь, все это имело смысл. Вы также должны проверить раздел ограничений статью в Википедии о представлении State State Transfer, если вы еще этого не сделали. Это особенно интересно в отношении того, что на самом деле аргументируют и почему объясняют принципы REST.

Ответ 3

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

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

  • Попробуйте GET /a без cookie
  • Вы получаете запрос на авторизацию как-то
  • Вы идете и авторизуетесь как-то вроде POST /auth
  • Вы получаете Set-Cookie
  • Попробуйте GET /a с помощью файла cookie. Но работает ли GET /a идемпотент в этом случае?

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

Ответ 4

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

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

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

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

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

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

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


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

Например, когда пользователь вводит данные в экран графического интерфейса пользователя, клиент отслеживает, какие поля были введены, а какие нет, какие-либо обязательные поля, которые отсутствуют. Это все CLIENT CONTEXT и не должно быть отправляется или отслеживается сервером. То, что отправляется на сервер, - это полный набор полей, которые необходимо изменить в ресурсе IDENTIFIED (посредством URI), так что переход происходит на этом ресурсе из одного состояния RESTful в другой.

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

Ответ 5

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

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

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

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

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

Для меня не так много способов поддерживать сеанс по HTTP. Можно использовать файлы cookie с sessionId или заголовок с sessionId.

Если у кого-то есть другая идея, я буду рад это услышать.

Ответ 6

  • Сеансы не RESTless
  • Вы имеете в виду, что служба REST только для http-use или у меня что-то не так? Сеанс на основе файлов cookie должен использоваться только для собственных (!) Http-сервисов! (Это может быть проблемой для работы с файлом cookie, например, с помощью Mobile/Console/Desktop/etc.)
  • если вы предоставляете услугу RESTful для разработчиков сторонних разработчиков, никогда не используйте сеанс на основе файлов cookie, вместо этого используйте токены, чтобы избежать проблем с безопасностью.