Действительно ли сессии нарушают RESTfulness? - PullRequest
456 голосов
/ 20 мая 2011

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

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

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

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

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

Мои предположения неверны? Что делает сеансовые куки RESTless ?

Ответы [ 6 ]

324 голосов
/ 20 мая 2011

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

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

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

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

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

280 голосов
/ 01 декабря 2013

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

  • RESTful:

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

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

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

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

    в соответствии с Fielding диссертацией .

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

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

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

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

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

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

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

Figure 1. - Stateless authentication by trusted clients

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

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

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

Figure 2. - Stateless authentication by 3rd party clients

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

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

12 голосов
/ 24 января 2013

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

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

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

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

7 голосов
/ 13 декабря 2013

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

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

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

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

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

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

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


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

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

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

1 голос
/ 16 июня 2015

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

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

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

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

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

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

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

0 голосов
/ 20 мая 2011
  1. Сессии не являются без RESTless
  2. Вы имеете в виду, что служба REST только для http-использования, или я что-то неправильно понял?Сеанс на основе файлов cookie должен использоваться только для собственных (!) Сервисов на основе http!(При работе с cookie может возникнуть проблема, например, из Mobile / Console / Desktop / etc.)
  3. , если вы предоставляете сервис RESTful для сторонних разработчиков, никогда не используйте сеанс на основе cookie, вместо этого используйте токеныпроблемы с безопасностью.
...