Аутентификация RESTful - что приводит к низкой производительности при высокой нагрузке?

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

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

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

  • Требуется ли БД для отдельной таблицы для хранения этих токены, индексированные по имени пользователя?
  • Предполагая, что токен хранится в БД, каждый запрос должен выполнить вызов БД. Разве это не делает сервер БД узким местом во времена высокой нагрузки?
  • Если токен на самом деле не хранится в БД, что является лучшим "спокойным" местом его хранения?
  • Сессия, вероятно, НЕ успокаивается, но тогда я не вижу, как уменьшится достоверность проверки подлинности/авторизации (w.r.t. выше)?
  • Если это НЕ токен, тогда нужно указать имя пользователя/пароль назад-вперед? (звучит как плохая идея:)

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

Итак, с теоретической/концептуальной точки зрения REST (необязательная реализация), как эта проблема обрабатывается (если вообще это проблема)? Как вы в своем профессиональном опыте справились с этой проблемой и как был подход Restful?

Мы работаем над веб-сервисом Restlet + J2EE + MySQL Restful, и у меня появился этот вопрос, но нет удовлетворительных ответов (Google, Stackoverflow и т.д.). Я знаю авторизацию HTTP Basic и Digest, но я не знакомы с внутренними элементами хранения/поиска в соответствии с приведенным выше объяснением.

Ответы

Ответ 1

Дух REST - безгражданство. Это не означает, что состояние клиента не может сохраняться службой, но на практике это означает, что состояние клиента , хранящееся в памяти сервером, как правило, плохое.

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

Что нужно хранить в файлах cookie для реализации "Запомнить меня" во время входа в систему пользователя

Итак, например, вы бы сделали следующее:

  • Когда клиент сначала связывается с сервисом, он не имеет cookie.
  • Вы выпускаете файл cookie, который содержит информацию о пользователе и "подписывает" его, используя вашу функцию (которую могут выполнять все серверы, выполняющие ваш код)
  • Когда клиент снова связывается с сервисом, вы проверяете, есть ли у него файл cookie; если нет, повторите (2).
  • Однако, если у него есть файл cookie, вы пытаетесь расшифровать (опять же, используя свою единственную функцию, которая реплицируется по всей вашей инфраструктуре) и убедитесь, что вы можете разворачивать и пересказывать эту информацию идентификатора пользователя.
  • Это проверяет пользователя и дает вам идентификационную информацию, все, не переходя в БД больше раз, чем это необходимо. И это RESTful.

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

Ответ 2

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

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

Ответ 3

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

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

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

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