Якщо програми REST повинні бути без громадянства, як ви керуєте сеансами?


536

Мені потрібно певне уточнення. Я читав про REST та створював RESTful програми. Згідно з Вікіпедією, сам REST визначається як Представницький державний трансфер . Тому я не розумію всього цього безгромадянського гурту, про який всі продовжують випирати .

З Вікіпедії:

У будь-який конкретний час клієнт може або переходити між станами програми, або «в стані спокою». Клієнт у стані спокою може взаємодіяти зі своїм користувачем, але не створює навантаження та не споживає клієнтського сховища на наборі серверів або в мережі.

Вони просто говорять, що не використовуйте сховище даних сеансу / рівня додатків ???

Я розумію, що однією метою REST є зробити доступ до URI послідовним та доступним, наприклад, замість того, щоб приховувати запити підкачки в публікаціях, роблячи номер сторінки запиту частиною GET URI. Має сенс для мене. Але здається, що це просто переборює, кажучи, що жодна інформація про клієнта (дані сесії) ніколи не повинна зберігатися на стороні сервера.

Що робити, якщо у мене була черга повідомлень, і мій користувач хотів прочитати повідомлення, але, читаючи їх, хотів заблокувати певних повідомлень відправників, які надходять протягом тривалості його сеансу? Хіба не було б сенсу зберігати це в місці, розташованому на стороні сервера, а сервер надсилає лише повідомлення (або ідентифікатори повідомлення), які не були заблоковані користувачем?

Чи дійсно мені потрібно надсилати весь список відправників повідомлень для блокування кожного разу, коли я запитую новий список повідомлень? Перелік відповідних мені списків повідомлень не повинен / не повинен бути навіть загальнодоступним ресурсом.

Знову ж таки, просто намагаюся це зрозуміти. Хтось прошу уточнити.


Оновлення:

Я знайшов запитання про переповнення стека, на який є відповідь, яка не зовсім мене переймає туди: як керувати державою в REST, яка говорить про те, що важливий стан клієнта повинен переноситися на кожен запит .... Ugg .. здається, що багато накладних ... Це правильно ??


2
@ S.Lott: Я не думаю, що це навмисно вводить в оману. Я думаю, що це непорозуміння через заплутану термінологію.
ДАЙТЕ МОЕ правильне ДУМКА

2
@ Справедливий мій правильний висновок: цікава здогадка. Я сам не міг повірити в таке, оскільки очевидно, що "без громадянства" означає, що сам протокол REST без громадянства; що нічого не говорить про базовий стан програми та оновлення його за допомогою запитів PUT, POST та DELETE.
S.Lott

@ S.Lott: Сам протокол HTTP не має статусу. З того, що ми обговорювали нижче, REST - це точка зору того, як створити додаток, не маючи стану веб-сервера обробляти стан сеансу (на відміну від інших видів стану в таких речах, як БД). Я навіть не думав, що REST - це протокол, а скоріше погляд на те, як використовувати протокол HTTP. Я подумав, що ви, хлопці, зрозуміли, що мова йде про те, як побудувати свою програму для масштабування за рахунок того, щоб клієнт зберігав усі дані, пов’язані з клієнтом, та робив доступ до URI якомога ідентичнішим, за винятком тих випадків, де вони не повинні бути. Можливо, ні ... :(
Зак

1
"Може, ні." Що це означає? У вас є нове запитання? Не соромтеся шукати ТАК для цього. Якщо його тут немає, то запитайте його.
S.Lott

Чи читав хтось на практиці Веббер, Парастатидіс та Робінсон (чи іншим чином бачив їх приклад решти)? Відповіді нижче мають сенс, але, безумовно, замовлення кави у прикладі restbucks - це стан клієнта? Кількість замовлень масштабується з кількістю клієнтів. Де знаходиться лінія між станом клієнта та ресурсом?
Рікі

Відповіді:


340

Без громадянства означає, що кожен запит HTTP відбувається у повній ізоляції. Коли клієнт робить HTTP-запит, він включає всю інформацію, необхідну серверу для виконання цього запиту. Сервер ніколи не покладається на інформацію з попередніх запитів. Якщо ця інформація була важливою, клієнту доведеться її надсилати ще раз у наступному запиті. Безгромадянство також приносить нові риси. Простіше розповсюджувати додаток без стану на серверах, збалансованих навантаженням. Додаток без громадянства також легко кешувати.

Насправді існує два види держави. Держава програми, яка живе на клієнті, і Ресурс, який живе на сервері.

Веб-сервісу потрібно дбати про стан вашої програми лише тоді, коли ви фактично робите запит. Решту часу він навіть не знає, що ти існуєш. Це означає, що кожен раз, коли клієнт робить запит, він повинен включати всі стани програми, яким сервер повинен буде його обробити.

Стан ресурсу однаковий для кожного клієнта, і його належне місце знаходиться на сервері. Завантажуючи зображення на сервер, ви створюєте новий ресурс: нова картинка має власний URI і може бути ціллю майбутніх запитів. Ви можете отримати, змінити та видалити цей ресурс через HTTP.

Сподіваюсь, це допомагає розрізнити, що означають безгромадянські та різні держави.


4
Чи означає це, що кожного разу, коли надсилається запит, клієнт повинен надсилати свого користувача / пароля для автентифікації? Тому що я думаю, що зберігання сеансу, навіть якщо він знаходиться на спільному не-sql db серед усіх серверів, не є без громадянства, чи так?
Карлос Наварро Астіасаран

1
@ CarlosNavarroAstiasarán існують різні методи обробки автентифікації без стану. Наприклад, JWT Google.
геодезик

1
@geoidesic: "Оскільки веб-маркери JSON без стану, немає способу їх визнати недійсним без збереження стану сервера, тим самим позбавивши переваги жетонів без стану". WIkipedia
ulatekh

@ulatekh Це грубе викривлення того, що ви можете зробити з жетонами. Зберігати затверджений ідентифікатор разом з маркером досить просто і приймати як марку лише маркери, які мають затверджений ідентифікатор. Без громадянства не означає, що ви не можете щось у базі даних. По суті, ви зберігаєте ідентифікатор у базі даних, який повинен відповідати тому самому ідентифікатору в маркері. Щоб відкликати маркер, ви видалите ідентифікатор із бази даних. Жодна держава не пам’ятається в самій службі. Або ще краще ви зберігаєте ключ підписання з користувачем у базі даних та відкликаєте ключ.
Ендрю Т Фіннелл

@AndrewTFinnell: Якщо вам потрібно зберегти затверджений ідентифікатор на сервері, він повинен зберігатися на всіх потенційних серверах, які могли б обробити логін REST, що може включати багато стану сервера в масово паралельній архітектурі веб-сервера.
ulatekh

491

Фундаментальне пояснення:

На сервері немає стану сеансу клієнта.

Під статусом без громадянства це означає, що сервер не зберігає жодного стану щодо клієнтського сеансу на стороні сервера.

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

Це не виключає, щоб інші сервіси, з якими розмовляє веб-сервер, підтримували стан таких бізнес-об'єктів, як кошики для покупок, лише не про поточний стан заявки / сеансу клієнта.

Стан програми клієнта ніколи не повинен зберігатися на сервері, а передаватися від клієнта до кожного місця, де це потрібно.

Ось звідки походить ST в REST , Державний трансфер . Ви передаєте стан навколо, а не зберігати його на сервері. Це єдиний спосіб масштабування мільйонів одночасних користувачів. Якщо з іншої причини, ніж через те, що мільйони сесій - це мільйони сесій.

Навантаження управління сеансом амортизується для всіх клієнтів, клієнти зберігають їх стан сеансів, а сервери можуть обслуговувати безліч замовлень або більше клієнтів без апарату.

Навіть для сервісу, який, на вашу думку, знадобиться лише 10-ти тисячам одночасних користувачів, ви все одно повинні зробити службу без громадянства. Десятки тисяч - це ще десятки тисяч, і з цим будуть пов'язані витрати на час і простір.

Без стану - це те, як протокол HTTP та Інтернет взагалі були розроблені для роботи та є загальною спрощеною реалізацією, і ви маєте єдиний шлях коду, а не купу логіки на стороні сервера, щоб підтримувати купу стану сеансу.

Існує кілька дуже основних принципів реалізації:

Це принципи, а не їх реалізація, як ви можете відповідати цим принципам.

Підсумовуючи, п'ять основних принципів :

  1. Дайте кожній «речі» посвідчення особи
  2. Зв’яжіть речі разом
  3. Використовуйте стандартні методи
  4. Ресурси з кількома представленнями
  5. Спілкуйтеся без громадянства

У дисертації REST немає нічого про автентифікацію чи авторизацію .

Тому що немає нічого відмінного від автентифікації запиту, який є ВІДПОВІДНИМ від того, якого немає. Перевірка автентичності не має значення для дискусії.

Пояснення, як створити додаток без громадянства для ваших конкретних вимог, є занадто широким для StackOverflow.

Реалізація автентифікації та авторизації, що стосується REST, ще більше настільки широка, і різні підходи до реалізації пояснюються дуже докладно в Інтернеті загалом.

Коментарі, які просять про допомогу / інформацію про це буде / повинні бути проставлені як " Більше не потрібно" .


22
Це здається досить сміливим твердженням, що це єдиний спосіб масштабувати мільйони користувачів. Чому серверні сеанси не можуть бути лише іншою послугою?
Зак

27
@Zak: Тому що мільйони сесій - це мільйони сесій. Суть у тому, щоб уникнути накладних витрат усього цього управління сеансом.
С.Лотт

91
це не сміливість, а досвід

21
Ніщо в моїй відповіді не передбачає рішення, засноване на доступі до бази даних за кожним запитом, якщо ви вважаєте, що це є, це з вашої сторони не зможе зрозуміти автентифікацію та авторизацію в такому масштабі. Аутентифікація може бути прихованою в державі, чи вважаєте ви, що Facebook робить "доступ до бази даних" на кожен запит його REST API? Або Google з цього питання? підказка: ні

6
Отже, якщо я зберігаю стан користувача у розподіленому кеші, наприклад, memcache, і весь мій веб-сервер зараз не потребує збереження будь-якого стану, а переходить і отримує стан з memcache, чи можу я вважати це додаток без громадянства?
Джаскі

76

Вони просто говорять, що не використовуйте сховище даних сеансу / рівня додатків ???

Ні. Вони не говорять про це тривіально.

Вони говорять, що не визначають "сеанс". Не входити. Не виходити з системи. Надайте облікові дані із запитом. Кожен запит стоїть окремо.

У вас ще є сховища даних. Ви все ще маєте автентифікацію та авторизацію. Ви просто не витрачаєте час на встановлення сеансів та підтримку стану сеансу.

Справа в тому, що кожен запит (a) стоїть повністю самостійно і (b) може бути тривіально оброблений до гігантської паралельної ферми серверів без будь-якої фактичної роботи. Apache або Squid можуть сліпо та успішно передавати RESTful запити.

Що робити, якщо у мене була черга повідомлень, і мій користувач хотів прочитати повідомлення, але, читаючи їх, хотів заблокувати певних повідомлень відправників, які надходять протягом тривалості його сеансу?

Якщо користувач хоче фільтра, то просто надайте фільтр на кожен запит.

Чи не було б сенсу ... сервер надсилав лише повідомлення (або ідентифікатори повідомлення), які не були заблоковані користувачем?

Так. Надайте фільтр у запиті RESTful URI.

Чи дійсно мені потрібно надсилати весь список відправників повідомлень для блокування кожного разу, коли я запитую новий список повідомлень?

Так. Наскільки великий може бути цей "список відправників повідомлень для блокування"? Короткий список ПК?

Запит GET може бути дуже великим. Якщо потрібно, ви можете спробувати POST-запит, хоча це звучить як своєрідний запит.


28
"Не входити в систему. Не виходити. Надайте облікові дані із запитом." Я завжди бачу подібні відповіді у питаннях про те, як залишатися без громадянства в API REST без будь-яких деталей про те, де / як потрібно зберігати ці облікові дані клієнта. Звичайно, ми не повинні зберігати ім'я користувача та пароль у локальному сховищі!
BeniRose

2
@BeniRose чи не можемо ми зберігати маркер у локальному сховищі та використовувати цей маркер у запитах, які однозначно ідентифікують користувача?
Нікхіл Саху

1
Місцеве зберігання має багато питань щодо безпеки, що стосується того, що я розумію. Але також існує маса інших проблем з клієнтськими сеансами, наприклад,
вимкнення

3
ви використовуєте JWT, які мають підпис, швидка перевірка підпису, щоб ви могли перевірити чинність цього стану.
Архімед Траяно

36

Ви абсолютно праві, що підтримка взаємодій без громадянства з сервером додатково обтяжує клієнта. Однак якщо врахувати масштабування програми, обчислювальна потужність клієнтів прямо пропорційна кількості клієнтів. Тому масштабування до великої кількості клієнтів набагато доцільніше.

Як тільки ви покладете на сервер невелику відповідальність за управління деякою інформацією, пов'язаною з взаємодією конкретного клієнта, цей тягар може швидко перерости в споживати сервер.

Це торг.


32

Історичний вигляд управління станом програмного забезпечення користувачів

Сесії в традиційному розумінні зберігають стан користувача в додатку всередині сервера. Це може бути поточна сторінка в потоці або те, що раніше було введено, але ще не зберігається в основній базі даних.

Причиною такої потреби стала відсутність стандартів для клієнта для ефективного підтримання стану, не роблячи конкретних для клієнта програм (тобто для браузера) додатків чи плагінів.

Запит HTML5 та заголовка XML з часом стандартизував поняття зберігання складних даних, у тому числі стан програми, стандартним способом на клієнтській (тобто браузерній) стороні, не вдаючись назад і назад між сервером.

Загальне використання REST-послуг

Послуги REST зазвичай називаються, коли є транзакція, яку потрібно виконати або якщо вона потребує отримання даних.

Послуги REST призначені для виклику клієнтською програмою, а не кінцевим користувачем безпосередньо.

Автентифікація

Для будь-якого запиту до сервера частина запиту повинна містити маркер авторизації. Те, як вона реалізується, залежить від додатків, але загалом це BASICабоCERTIFICATE форма аутентифікації.

Служби REST не використовують аутентифікацію на основі форми. Однак, як зазначалося вище, послуги REST призначені не для виклику користувача, а програми. Додаток повинен керувати отриманням маркера аутентифікації. У моєму випадку я використовував файли cookie з JASPIC з OAuth 2.0 для підключення до Google для аутентифікації та просту аутентифікацію HTTP для автоматизованого тестування. Я також використовував аутентифікацію заголовка HTTP через JASPIC для локального тестування (хоча такий же підхід можна виконати і в SiteMinder)

Згідно з цими прикладами, автентифікацією керується на стороні клієнта (хоча SiteMinder або Google зберігали б сеанс аутентифікації на їх кінці), нічого не можна зробити для цього стану, але це не є частиною додатку служби REST.

Запити на пошук

Запити на пошук в REST - це GETоперації, де запитується певний ресурс і є кешованим. У сеансах на сервері немає необхідності, оскільки у запиті є все необхідне для отримання даних: аутентифікація та URI.

Сценарії транзакцій

Як зазначалося вище, додаток на стороні клієнта сам викликає служби REST разом з аутентифікацією, якою він керує і на стороні клієнта.

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

Це робиться через a POSTЗазвичай запит, але PUTможуть використовуватися й інші, такі як .

Дуже багато надуманих прикладів REST (я сам це робив) намагався прослідкувати якнайбільше того, що було визначено в протоколі HTTP, після того як я пройшов через це, я вирішив бути більш прагматичним і залишив це лише GET і POST . POSTМетод навіть не повинен реалізувати шаблон POST-Redirect-GET.

Незважаючи на те, що, як я вже зазначав вище, додаток на стороні клієнта буде тим, хто викликає службу, і він буде дзвонити тільки на POST запит лише з усіма даними, коли це потрібно (не кожен раз). Це запобігає постійним запитам до сервера.

Опитування

Хоча REST може бути використаний і для опитування, я не рекомендую його, якщо вам не доведеться використовувати його через сумісність браузера. Для цього я б використовував WebSockets, на який я також розробив контракт API . Ще одна альтернатива для старих браузерів - CometD.


27

REST дуже абстрактний. Це допомагає мати кілька хороших, простих, реальних прикладів.

Візьмемо для прикладу всі основні програми соціальних медіа - Tumblr, Instagram, Facebook та Twitter. Усі вони мають вічно прокручуваний вид, де чим далі ви прокручуєте вниз, тим більше вмісту ви бачите, тим далі і далі назад у часі. Однак ми всі пережили той момент, коли ви втрачаєте місце, де ви прокручувались, і додаток скидає вас на вершину. Як якщо ви закриєте додаток, то, коли ви знову відкриєте його, ви знову опинитесь у верхній частині.

Причина тому, що сервер не зберігав ваш стан сеансу. На жаль, ваша позиція прокрутки була просто збережена в оперативній пам’яті на клієнті.

На щастя, вам не доведеться входити в систему, коли ви знову підключитесь, але це лише тому, що сертифікат для входу на стороні клієнта також не закінчився. Видаліть і перевстановіть додаток, і вам доведеться знову увійти, оскільки сервер не пов’язував вашу IP-адресу з вашим сеансом.

У вас немає сеансу входу на сервері, оскільки вони дотримуються REST.


Тепер наведені вище приклади взагалі не включають веб-браузер, але на звороті, додатки спілкуються через HTTPS з їх хост-серверами. Моя думка полягає в тому, що REST не повинен залучати файли cookie та браузери тощо. Існують різні способи зберігання стану сеансу на стороні клієнта.

Але давайте поговоримо про веб-браузери на секунду, бо це дає ще одну головну перевагу REST, про яку тут ніхто не говорить.

Якщо сервер намагався зберігати стан сеансу, то як слід ідентифікувати кожного окремого клієнта?

Він не міг використовувати їх IP-адресу, оскільки багато людей могли використовувати ту саму адресу на спільному маршрутизаторі. То як же тоді?

Він не може використовувати MAC-адресу з багатьох причин, що не в останню чергу тому, що ви можете одночасно входити в різні облікові записи Facebook у різних браузерах та додатку. Один веб-переглядач може легко прикинутися іншим, а MAC-адреси так само легко піддаються.

Якщо сервер повинен зберігати певний стан клієнта, щоб ідентифікувати вас, він повинен зберігати його в оперативній пам’яті довше, ніж просто час, який потрібно для обробки ваших запитів, інакше він повинен кешувати ці дані. Сервери мають обмежену кількість оперативної пам’яті та кешу, не кажучи вже про швидкість процесора. Стан на стороні сервера додається до всіх трьох, експоненціально. Плюс якщо сервер збирається зберігати будь-який стан щодо ваших сеансів, він повинен зберігати його окремо для кожного веб-переглядача та програми, з якою ви зараз увійшли, а також для кожного іншого пристрою, який ви використовуєте.


Отже ... Я сподіваюся, що зараз ви зрозумієте, чому REST настільки важливий для масштабованості. Я сподіваюся, що ви можете почати розуміти, чому стан сеансу на стороні сервера - це масштабність сервера, що таке приварені ковадли для прискорення автомобіля.


Де люди плутаються, думаючи, що "стан" посилається на, наприклад, інформацію, що зберігається в базі даних. Ні, вона посилається на будь-яку інформацію, яка повинна бути в оперативній пам'яті сервера під час її використання.


13

Я бачу, що основним питанням тут є змішування сесії з State . І хоча REST вказує, що НЕ слід зберігати стан на сервері, ніщо не заважає зберігати сеанс користувача .

Управління державою на сервері означає, що ваш сервер точно знає, що робить клієнт (яку сторінку вони переглядають, у якому розділі програми). І це те, що вам не потрібно було робити.

Я погоджуюся з іншими людьми, які говорять про те, що слід зберігати зберігання сеансу до мінімального розміру; і хоча це здоровий глузд, він фактично також залежить від програми. Отже, коротше кажучи, ви все ще можете тримати сеанс із кешованими даними для обробки запитів із меншим навантаженням на сервер та керування автентифікацією, надаючи тимчасовий маркер автентифікації / доступу для клієнта. Щоразу, коли сеанс / маркер закінчився, створіть новий і попросіть клієнта використовувати його.

Хтось може заперечити, що клієнт повинен краще генерувати маркер. Я кажу, що це працює обома способами, і це залежатиме від програми та того, хто буде працювати з API.

Також правильним способом має стати збереження на сервері деяких чутливих даних сеансу. Ви не можете довіряти клієнту зберігати кошик, який (наприклад) містить поле з назвою "isFreeGift". Така інформація повинна зберігатися на сервері.

Відео посилання, яке надав Сантану Дей у своїй відповіді, є корисним. Слідкуйте за цим, якщо ви цього не зробили.

Лише побічна примітка: Схоже, що всі відповіді, які вже були надіслані, здається, не враховують того, що деякі операції можуть спричинити велике навантаження на сервер. Це актуально з точки зору енергоспоживання, споживання обладнання та вартості (для серверів, орендованих циклом процесора). Хороший розробник не повинен лінуватися оптимізувати їх застосування, навіть якщо операція може бути виконана дуже швидко на сучасному процесорі на якомусь орендованому сервері, за який вони не платять свій рахунок за електроенергію та обслуговування.

Але все-таки питання пройшло кілька років, я сподіваюся, що моя відповідь все-таки буде корисною.


4
Я загалом погоджуюся з цим настроєм, але останнім часом тенденція стверджує, що навіть ідентифікатор сеансу не повинен зберігатися на сервері. Я ще не повинен з'ясувати, яке альтернативне рішення, JWT добре рекламується, але приходить з пригорщами gotchas: cryto.net/~joepie91/blog/2016/06/19/…
BeniRose

11

Без громадянства означає, що стан служби не зберігається між наступними запитами та відповідями. Кожен запит містить власні облікові дані користувачів та індивідуально засвідчується. Але в заяві кожен запит відомий з будь-якого попереднього запиту. Усі запити, надіслані станом, орієнтовані на сеанс, тобто кожен запит повинен знати та зберігати зміни, внесені в попередніх запитах.

Банківський додаток - приклад успішного застосування. Там, де користувач спочатку входить у систему, тоді здійснюють транзакції та виходять із системи. Якщо після виходу користувач спробує здійснити транзакцію, він не зможе цього зробити.

Так, протокол http по суті є протоколом без громадянства, але щоб зробити його державним, ми створюємо нам файли cookie HTTP. Отже, SOAP за замовчуванням. Але це може бути також надзвичайним, залежно від структури, яку ви використовуєте.

HTTP без стану, але все ж ми можемо підтримувати сеанс у нашому додатку Java, використовуючи різні механізми відстеження сеансів.

Так, ми також можемо підтримувати сеанс у веб-сервісі, будь то REST чи SOAP. Він може бути реалізований за допомогою будь-якої сторонньої бібліотеки або ви можете реалізувати власну.

Взято з http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap


11

Ложки немає.

Не думайте про безгромадянське становище, як " знову і знову надсилайте всі свої речі на сервер". У жодному разі. Буде стан, завжди - сама база даних - це своєрідний стан, адже ви зареєстрований користувач, тому будь-який набір інформації на стороні клієнта не буде дійсним без сторони сервера. Технічно ти ніколи не буваєш справді без громадянства.

Слово про щомісячну дискусію про вхід

Що навіть означає не тримати сеанс і входити в систему кожного разу? Деякі означають "надсилати пароль кожен раз", це просто нерозумно. Деякі кажуть "так, звичайно, ні, надішліть маркер замість цього" - ось, ось PHP сесія робить майже саме це. Він надсилає ідентифікатор сеансу, який є своєрідним маркером і він допомагає вам дістатися до ваших особистих речей, не повторно пересилаючи u / pw кожен раз. Він також досить надійний і добре перевірений. І так, зручно, що може обернутися недоліком, дивіться наступний параграф.

Зменшити слід

Що ви повинні зробити , а натомість, і що має справжній сенс, це зменшити ваш мінімум слід веб-сервера. Такі мови, як PHP, дозволяють просто заповнити все, що зберігається в сеансі, але сеанси мають ціну. Якщо у вас є декілька веб-серверів, їм потрібно ділитися інформацією про сеанс, оскільки вони також діляться завантаженням - будь-який з них, можливо, повинен буде подати наступний запит.

Спільне сховище є обов'язковим. Сервер повинен знати щонайменше, чи хтось увійшов чи ні. (І якщо ви турбуєте базу даних кожного разу, коли вам потрібно вирішити це, ви практично приречені.) Спільні сховища повинні бути набагато швидшими, ніж база даних. Це приносить спокусу: гаразд, у мене дуже швидке зберігання, чому б не зробити все там? - і ось там справи йдуть неприємно інакше.

Отже, ви говорите: звести до мінімуму зберігання сеансу?

Знову ж таки, це ваше рішення. Ви можете зберігати там речі з міркувань продуктивності (база даних майже завжди повільніше, ніж Redis), ви можете зберігати інформацію надмірно, реалізовувати власне кешування, будь ласка - майте на увазі, що веб-сервери матимуть більше навантаження, якщо ви зберігаєте багато сміття. на них. Крім того, якщо вони зламаються під великими навантаженнями (і вони будуть), ви втрачаєте цінну інформацію; з REST способом мислення, все, що трапляється в цьому випадку, - клієнт знову надсилає той самий (!) запит, і він цього разу обслуговується.

Як це зробити правильно?

Тут немає жодного рішення. Я б сказав, вибрати рівень без громадянства і піти з цим. Сеанси одні можуть любити, а інші ненавидіти, але вони нікуди не йдуть. З кожним запитом надсилайте стільки інформації, скільки має сенс, трохи більше, можливо; але не інтерпретуйте безгромадянське становище як не сеанс, ні щоденний запис. Якось сервер повинен знати, що це ти ; Ідентифікатори сеансів PHP - хороший спосіб, жетони - інший.

Подумайте та вирішіть, не дозволяйте тенденціям дизайну думати за вас.


1
"Подумайте та вирішіть, не дозволяйте тенденціям дизайну думати за вас". на жаль, в наші дні стало дуже поширеним просто тупо слідувати тенденціям. Іноді читаючи ТАК, ви отримаєте однакові відповіді саме через тенденцію.
l00k

Так, я бачив це навколо багатьох тем, і коли я усвідомлюю, що відбувається, іноді перестаю сперечатися. Тоді всі збожеволіли від того, наскільки вміст боксу кращий за межі; це був один із способів проявити ненависть до IE. Потім прийшов завантажувальний апарат і раптом усі стали прихильником кордону. Тенденції приходять, але потім вони йдуть. Використовуйте goto, використовуйте таблиці, використовуйте iframes, просто знайте, що ви робите і чому. Трендалісти спробують вас збити, потім вони зареєструються та оплатять ваш сайт. Світ знову врятувався.
dkellner

@dkellner Я не зрозумів цю частину: "Сервер повинен знати принаймні, чи хтось увійшов чи ні. (І якщо ви турбуєте базу даних кожен раз, коли вам потрібно це вирішити, ви практично приречені.)". Скажімо, ви зберігаєте дані сеансу в базі даних за допомогою PHP. Чому запит у БД для входу в систему поганий (приречене - це сильне слово), так як у будь-якому разі буде багато поданих запитів БД для отримання повних даних користувачів та інших матеріалів на основі ідентифікатора сесії PHP? Іншими словами, запити БД неминучі в будь-якому випадку. Крім того, якщо ви не отримуєте ідентифікатор сеансу PHP, ви знаєте, що користувач неаутентифікований, не потрібно запитувати.
користувач2923322

Коли у вас є тисячі або навіть мільйони користувачів, ви не можете дозволити собі розкіш підключення до db кожного разу, коли ви хочете зробити кепалівінг, оновлення місцезнаходження, опитування повідомлень або все, що потребує короткого заїзду. Ви повинні реалізовувати ці дзвінки без доступу до бази даних (або з мінімальним), тому я кажу, що це може бути смертельним, якщо ви будуєте всю свою концепцію навколо db. Знову ж таки, можуть бути випадки, коли добре розроблене рішення db буде працювати, але типовий програміст вирішить що завгодно, сказавши "добре, спочатку ми підключимо та отримаємо деяку інформацію про користувача". Бааада практика.
dkellner

5

Погляньте на цю презентацію.

http://youtu.be/MRxTP-rQ-S8

За цією схемою - створюйте перехідні спокійні ресурси для управління державою, якщо і коли це дійсно потрібно. Уникайте явних сеансів.


1
Прочитайте, будь ласка, як я можу написати гарну відповідь? перш ніж спробувати відповісти на додаткові запитання.

3

Основна відмінність стану без громадянства від Stateful полягає в тому, що дані щоразу передаються на сервер. У випадку без громадянства клієнт повинен надати всю інформацію, тому в кожному запиті може знадобитися передати багато параметрів. У програмі Stateful клієнт передає ці параметри один раз, і вони підтримуються сервером, поки клієнт не змінить їх знову.

IMO, API повинен бути без стану, що дає змогу масштабувати дійсно швидко.


2

Ви повинні керувати сеансом клієнта на стороні клієнта. Це означає, що вам потрібно надсилати дані автентифікації з кожним запитом, і ви, мабуть, але не обов'язково маєте кеш-пам’ять на сервері, який поєднує дані аутентифікації з інформацією користувача, як-от ідентифікація, дозволи та ін.

Це обмеження без громадянства в REST дуже важливе. Без застосування цього обмеження ваша програма на стороні сервера не буде мати масштабів , тому що підтримка кожного окремого сеансу клієнта буде його ахілесовою п’ятою .


Якщо ви надсилаєте дані про автентифікацію з кожним запитом, куди / як ви зберігаєте облікові дані клієнта, щоб користувачеві не потрібно було повторно вводити його під час кожного запиту?
Бурштин

1

Коли ви розробляєте послугу RESTful, для входу в систему вам знадобиться автентифікація вашого користувача. Можливим варіантом буде надіслати ім'я користувача та пароль кожного разу, коли ви маєте намір здійснити дії користувача. У цьому випадку сервер взагалі не буде зберігати дані сеансу.

Інший варіант - генерувати сеанс-ідентифікатор на сервері та відправляти його клієнтові, тож клієнт зможе надіслати сеанс-ідентифікатор на сервер та пройти автентифікацію. Це набагато безпечніше, ніж щоразу надсилати ім’я користувача та пароль, оскільки якщо хтось отримує руку над цими даними, то він / вона може видавати себе за користувача, доки ім’я користувача та пароль не будуть змінені. Ви можете сказати, що навіть ідентифікатор сеансу може бути викрадений, і користувач в такому випадку буде себе представляти собі, і ви маєте рацію. Однак у цьому випадку видання себе за користувача буде можливим лише тоді, коли ідентифікатор сеансу дійсний.

Якщо API RESTful очікує імені користувача та пароля, щоб змінити ім’я користувача та пароль, то навіть якщо хтось видав себе за особу, використовуючи ідентифікатор сеансу, хакер не зможе заблокувати реального користувача.

Ідентифікатор сеансу може бути згенерований шляхом одностороннього блокування (шифрування) чогось, що ідентифікує користувача та додавання часу до ідентифікатора сеансу, таким чином можна визначити час закінчення сеансу.

Сервер може або не може зберігати ідентифікатори сеансу. Звичайно, якщо сервер зберігає ідентифікатор сеансу, то це порушило б критерії, визначені у питанні. Однак важливо лише переконатися, що ідентифікатор сеансу може бути перевірений для даного користувача, що не потребує збереження ідентифікатора сеансу. Уявіть, що у вас є одностороннє шифрування електронної пошти, ідентифікатора користувача та деяких приватних приватних даних, наприклад, улюблений колір, це був би перший рівень і якимось чином додав дату імені користувача до зашифрованого рядка та застосуйте дво- спосіб шифрування. У результаті, коли отримано ідентифікатор сеансу, другий рівень може бути розшифрований, щоб можна було визначити, яким іменем користувача користувач претендує на те, і чи правильний час сеансу. Якщо це дійсно, тоді перший рівень шифрування можна перевірити, повторивши це шифрування і перевіривши, чи відповідає він рядку. Для цього вам не потрібно зберігати дані сеансу.


це має сенс
поспіх

0

Вся концепція різна ... Вам не потрібно керувати сеансами, якщо ви намагаєтесь реалізувати протокол RESTFul. У такому випадку краще провести процедуру аутентифікації за кожним запитом (тоді як для неї є додаткові витрати з точки зору продуктивності - хеш-пароль буде хорошим прикладом. Не велика справа ...). Якщо ви використовуєте сеанси - як можна розподілити навантаження на декілька серверів? Я думаю, що протокол RESTFul призначений для усунення сеансів - вони вам насправді не потрібні ... Ось чому його називають "без громадянства". Сеанси потрібні лише тоді, коли ви не можете зберігати нічого іншого, крім Cookie, на стороні клієнта після того, як зроблено запит (наприклад, візьміть старий, не підтримуючий Javascript / HTML5 браузер). У разі "повнофункціонального" клієнта RESTFul зберігати його зазвичай безпечноbase64(login:password) на стороні клієнта (в пам'яті), поки додаток все ще не завантажено - програма використовується для доступу до єдиного хоста, а файли cookie не можуть бути порушені сторонніми сценаріями ...

Я настійно рекомендую вимкнути аутентифікацію файлів cookie для RESTFul-серверів ... перевірити Basic / Digest Auth - цього повинно вистачити для послуг на базі RESTFul.


3
Що таке a client side (in memory) і як безпечно економити base64(login:password)на стороні клієнта?
RN Kushwaha

1
Ніщо не визначається як "повністю безпечне". Однак ви можете розглянути можливість використання OAuth2, що забезпечує кращу безпеку, ніж збереження рядка base64 для запиту API (Basic Auth), якщо ви тримаєтесь на Basic auth, для кращої безпеки можна використовувати HTTPS.
felixwcf

3
Р. Кушваха, на це питання, на який, схоже, ніхто не хоче відповідати, коли вони скажуть вам припинити зберігання сеансу на сервері та зберігати його у клієнта.
BeniRose

0

REST не має статусу і не підтримує жодних станів між запитами. Файли cookie / заголовки клієнта встановлюються для підтримання стану користувача, такого як аутентифікація. Скажімо, ім'я користувача / пароль клієнта підтверджено механізмом аутентифікації третьої частини - поширенням OTP 2-го рівня тощо. Після того, як користувач отримає автентифікацію - заголовки / файли cookie вийдуть на кінцеву точку служби спокою, і ми можемо вважати, що користувач є автентичним, оскільки користувач приходить з дійсними заголовками / cookie . Тепер певна інформація про користувача, як-от IP, або зберігається в кеші, і після цього, якщо запит надходить з того ж Ip (mac-адреси) для перелічених ресурсів, користувач дозволений. І кеш підтримується протягом певного часу, який стає недійсним, коли проходить час. Таким чином, або кеш-пам'ять може бути використана, або записи БД можуть бути використані для збереження інформації в / в запитів.


0

Тут без стану означає, що стан або метадані запиту не підтримуються на стороні сервера. Підтримуючи кожен запит або стан користувача на сервері, це призведе до вузьких місць. Сервер просто запитується з необхідними атрибутами для виконання будь-яких конкретних операцій.

Що стосується керування сеансами чи надання персоналізованого досвіду користувачам, воно потребує підтримки деяких метаданих або стану користувальницьких переваг користувача, історії минулих запитів. Це можна зробити, зберігаючи файли cookie, приховані атрибути або об’єкт сеансу.

Це може підтримувати або відстежувати стан користувача в додатку.

Сподіваюся, це допомагає!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.