Чи можете ви допомогти мені зрозуміти це? "Поширені помилки REST: сесії не мають значення"


159

Відмова: Я новачок у школі REST думки, і я намагаюся обернути свою думку.

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

У клієнта не повинно бути "входу" або "початку зв'язку". Ідентифікація HTTP проводиться автоматично на кожному повідомленні. Клієнтські програми - це споживачі ресурсів, а не послуг. Тому увійти в систему нема чого! Скажімо, ви бронюєте рейс на веб-сервісі REST. Ви не створюєте нове "сеансове" з'єднання зі службою. Швидше ви попросите "об'єкта маршруту творця" створити вам новий маршрут. Ви можете почати заповнювати заготовки, але потім отримати якийсь абсолютно інший компонент в іншому місці в Інтернеті, щоб заповнити деякі інші заготовки. Немає сеансу, тому немає проблеми з переходом стану сеансу між клієнтами. Також немає питання про "спорідненість сеансу"

Гаразд, я розумію, що аутентифікація HTTP робиться автоматично на кожному повідомленні - але як? Чи ім'я користувача / пароль надсилаються з кожним запитом? Це не просто збільшує площу поверхні атаки? Я відчуваю, що мені не вистачає частини головоломки.

Було б погано мати службу REST, скажімо, /sessionщо приймає GET-запит, де ви передасте ім'я користувача / пароль як частину запиту та повертаєте маркер сеансу, якщо аутентифікація пройшла успішно, це може бути тоді передано разом з подальшими запитами? Це має сенс з точки зору REST, або це не вистачає точки?


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

Відповіді:


79

Щоб бути RESTful, кожен запит HTTP повинен нести в собі достатню кількість інформації для свого одержувача, щоб обробити його в повній гармонії з природою HTTP без громадянства.

Гаразд, я розумію, що аутентифікація HTTP робиться автоматично на кожному повідомленні - але як?

Так, ім'я користувача та пароль надсилаються з кожним запитом. Загальні методи для цього - це автентифікація базового доступу та аутентифікація доступу . І так, підслуховувач може захоплювати облікові дані користувача. Таким чином, можна зашифрувати всі дані, надіслані та отримані за допомогою безпеки транспортного рівня (TLS) .

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

Це не було б RESTful, оскільки воно містить стан, але, однак, досить часто, оскільки це зручність для користувачів; користувачеві не потрібно кожного разу входити в систему.

Те, що ви описуєте в "маркері сеансу", зазвичай називають файлом cookie . Наприклад, якщо ви намагаєтеся увійти до свого Yahoo! у акаунті є прапорець, у якому написано "тримати мене увійти протягом 2 тижнів". Це, по суті, говорить (за вашими словами) "збережіть мою сексінну марку протягом двох тижнів, якщо я успішно ввійду в систему". Веб-браузери надсилатимуть такі файли cookie для входу (і, можливо, інші) з кожним запитом HTTP, який ви попросите зробити для вас.


5
Ця відповідь для мене не має сенсу. По-перше, в ньому йдеться про те, що нормально кожного разу передавати логін та пароль, а отже і один раз, що має сенс. Потім пропонується ідея повернути клієнту стан успішного входу у вигляді лексеми. При необхідності маркер може кодувати час створення. Нам, безумовно, дозволяється повернути інформацію клієнту. Отже, ця пропозиція мені здається прекрасною. У відповіді сказано, що це не добре, оскільки "він містить стан", але чи не ідея "ST" у "REST" про те, що стан може бути перенесений між клієнтом і сервером?

33

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


3
+1, чи можете ви уточнити: чи обмежений вигляд для зловмисника, який його перехоплює (оскільки він базується на поточному часу) ? Ви не говорите про файл cookie, який містить зашифроване ім’я користувача та пароль? як це робить? (ІМХО)
Рой Намір

2
@RoyiNamir: Я не говорю про печиво. Підпис, використовуваний S3, є параметром для запиту HTTP, але не є файлом cookie, він перераховується для кожного запиту.
Грег Хьюгілл

Тож, якщо мені потрібно зберегти якусь інформацію про користувача, то де я би її зберігав? в дб? Я не хочу відправляти кожен запит на db .... і все ще я хочу використовувати відпочинок .... чи можете ви допомогти?
Рой Намір

@RoyiNamir: Якщо у вас є конкретні питання щодо того, як досягти певної мети, будь ласка, задайте нове запитання . Я не можу відповісти на додаткові запитання тут у коментарях.
Грег Хьюгілл

10

Багато людей не розуміють принципів REST дуже чітко, використовуючи маркер сеансу, це не означає, що ви завжди заявляєте про себе, причина надсилати ім’я користувача / пароль з кожним запитом полягає лише в автентифікації та однакові для надсилання токена (генерованого при вході в систему процес), щоб вирішити, чи має клієнт дозвіл на запит даних чи ні, ви порушуєте конвенції REST лише тоді, коли ви використовуєте або ім’я користувача / пароль, або секельні маркери, щоб вирішити, які дані показувати! натомість ви повинні використовувати їх лише для аутентифікації (для показу даних чи не для показу даних)

у вашому випадку я кажу ТАК, що це RESTy, але спробуйте уникати використання нативної сесії PHP у вашому API REST і починайте генерувати власні хешовані маркери, які закінчуються у визначений період часу!


1
спасибі. Чому слід уникати рідних сеансів PHP і використовувати замість них власні хеш-маркери?
Метью

Я не кажу про будь-яку геніальну причину, просто для більшої безпеки та більшого контролю.
EvilThinker

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

8

Ні, це не пропускає суть. ClientLogin Google працює точно таким чином, за винятком того, що клієнту доручено перейти до "/ сесії" за допомогою відповіді HTTP 401. Але це не створює сеанс, це лише створює спосіб для клієнтів (тимчасово) аутентифікувати себе, не передаючи облікові дані в поле очищення, а сервер контролювати дійсність цих тимчасових облікових даних, як вважає за потрібне.


11
@ unsgiven3 Поки повернений маркер використовується лише для автентифікації користувача, а сервер не використовується для асоціації користувача з іншим станом, що зберігається на сервері, я не бачу, щоб жодних обмежень REST не було порушено.
Даррел Міллер

4
@ unsgiven3 Маркер, повернений сервером, фактично є доказом того, що користувач є тим, про кого вони кажуть. Отже, замість кожного запиту, включаючи ім'я користувача та пароль, кожен запит включає маркер, який побудований таким чином, що сервер може бути впевнений у своїй правдивості.
Даррел Міллер

1
@ unsgiven3, Даррел має рацію. Токен повторно повинен був надсилатись клієнтом на кожен запит HTTP, як і в базовій, дайджест аутентифікації, поки термін не закінчиться. Коли це станеться, клієнт може повторити вхід, необов'язково запитавши у користувача облікові дані або будь-що інше. Я можу розробити відповідь, якщо хочете. редагувати: (І дякую, що не відставали від відповідей на старі запитання!)
mogsie

1
Немає проблем, могсі, завжди цікаво обговорювати такі речі :-) Я думаю, що я бачу, куди ви з цим рухаєтесь, хлопці, на жаль, я просто не розумію достатньо автентичності дайджесту, щоб дійсно зрозуміти це (в основному я просто не знаю зрозуміти, як маркер відсилається назад кожного запиту HTTP, але це, здається, є детальною інформацією про реалізацію). Однак зараз я розумію, чому цей метод не порушує принципів REST. Дякуємо за відповіді!
Роб

6
@ unsgiven3, Це може допомогти: маркер - це підписана інформація. Значить, вона є самодостатньою. Сервер може перевірити маркер, не перевіряючи попередньо збережений стан. Отже, це лише стан, який зберігається на клієнті і передається туди-сюди.
Іраванчі

5

Гаразд, я розумію, що аутентифікація HTTP робиться автоматично на кожному повідомленні - але як?

"Авторизація:" HTTP-заголовок, надісланий клієнтом. Або основний (звичайний текст), або дайджест.

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

Вся ідея сеансу полягає в тому, щоб зробити справжні програми, використовуючи протокол без стану (HTTP) та німий клієнт (веб-браузер), підтримуючи стан на стороні сервера. Один із принципів REST - "Кожен ресурс однозначно адресований за допомогою універсального синтаксису для використання в гіперпосередкових посиланнях" . Змінні сесії - це те, до чого не можна отримати доступ через URI. Дійсно програма RESTful підтримувала б стан на стороні клієнта, надсилаючи всі необхідні змінні через HTTP, бажано в URI.

Приклад: пошук з використанням сторінки. У вас буде URL-адреса у формі

http://server/search/urlencoded-search-terms/page_num

Має багато спільного з закладеними URL-адресами


4
Інформація про автентифікацію недоступна і через URI, хоча всі говорять про надсилання інформації про автентифікацію як частина заголовка запиту. Чим це відрізняється від включення маркер сесії до запиту? Я не кажу про використання маркера сеансу в URI, але в даних, переданих у запиті.
Роб

Аутентифікація встановлює, якщо ви уповноважені виконувати цю дію, а в додатку RESTful це не вплине на її результат.
vartec

4
Маркер сеансу також встановлює, чи маєте ви право на виконання цієї дії. Що ви маєте на увазі, що це не вплине на результат? Якщо абонент не авторизований, він отримує помилку Не авторизований. Те ж саме з маркером сеансу. Я справді не бачу різниці?
Роб

3
Ні, маркер сеансу - це ручка для збереження стану на сервері. Це просто не ВІДПОВІДНО. Щодо Недозволених, я не бачу цього в результаті. Я вважаю, що це виняток (як у пробі / лові).
vartec

Досить справедливо, vartec - це має сенс. Дякуємо за подальші дії!
Роб

3

Я думаю, що з вашою пропозицією добре, якщо ви хочете контролювати час життя сеансу клієнта. Я думаю, що архітектура RESTful спонукає вас розробляти програми без громадянства. Як писав @ 2pence, "кожен запит HTTP повинен нести в собі достатню кількість інформації для свого одержувача, щоб обробляти його в повній гармонії з природою HTTP без громадянства" .

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

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