Шаблон входу в API REST API


181

Я створюю REST api, уважно дотримуюся пропозицій apigee, використовуючи іменники не дієслова, версію api, запечену в URL, два шляхи api на колекцію, GET POST PUT DELETE використання тощо.

Я працюю над системою входу, але не впевнений у правильному способі REST для входу в систему користувачів. На даний момент я не працюю над безпекою, просто входом або потоком входу. (Пізніше ми будемо додавати два кроки oAuth, з HMAC тощо)

Можливі варіанти

  • POST на щось подібне https://api...com/v1/login.json
  • ПУТ на щось подібне https://api...com/v1/users.json
  • Щось мені не хотілося ...

Який належний стиль REST для входу в систему користувачів?


9
Такий формат відповідей. .json повідомляє серверу відповісти за допомогою json, .xml каже серверу відповісти у форматі xml. Швидше, щоб зробити його необов'язковим параметром позаду ?. blog.apigee.com/detail/…
Скотт Ропнак

28
Ніколи не бачив переговорів щодо вмісту за URL-адресою, лише в заголовках. За URL-адресою це означає, що ви втрачаєте переваги кешування та багато іншого.
Одед

10
@ScottRoepnack, тоді вам слід розглянути Acceptзаголовок HTTP.
Алессандро Вендрусколо

2
@Oded Якщо ви використовували Acceptзаголовок, ви також матимете "" Vary: Accept, тому кешування не вплине. Conneg в розширенні вже обговорювалося раніше ; Я б погодився з відповіддю Шонзілли там.
cmbuckley

2
@ Додано - я не розумію. чому б ви втратили користь кешування, якщо вказати тип вмісту в URL-адресі (або як суфікс .json до шляху запиту, або як параметр запиту type = json)? А хто "ти" в цьому випадку? Хто та людина, яка втрачає переваги кешування? мені здається, що результати будь-якого запиту можна кешувати незалежно від того, що знаходиться в шляху запиту чи парамах.
Чесо

Відповіді:


138

Принциповий дизайн сучасної веб-архітектури Роя Т. Філдінга та Річарда Н. Тейлора , тобто послідовність робіт із усієї термінології REST, містить визначення взаємодії клієнт-сервер:

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

Це обмеження виконує чотири функції, перша і третя важливі в даному конкретному випадку:

  • По-перше : це усуває будь-яку потребу в роз'ємах, щоб зберегти стан програми між запитами , таким чином зменшивши споживання фізичних ресурсів та покращивши масштабованість;
  • 3-те : це дозволяє посереднику переглядати та розуміти запит поодиноко , що може знадобитися, коли служби динамічно переставляються;

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

Одним із прикладів того, як це зробити архівним способом, є код аутентифікації на основі хешу або HMAC . На практиці це означає додати хеш-код поточного повідомлення до кожного запиту. Хеш-код, розрахований за допомогою криптографічного хеш-функції в поєднанні з секретним криптографічним ключем . Криптографічна хеш-функція є або заздалегідь визначеною, або частиною концепції REST за запитом коду (наприклад, JavaScript). Секретний криптографічний ключ повинен надаватися сервером клієнтові як ресурс, і клієнт використовує його для обчислення хеш-коду для кожного запиту.

Прикладів реалізації HMAC дуже багато , але я хотів би, щоб ви звернули увагу на наступні три:

Як це працює на практиці

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

Сподіваюся, що це допоможе вам знайти правильне рішення!


23
MAC призначений для підтвердження автентичності повідомлення та захисту від підробки - це не має нічого спільного з автентифікацією користувача
yrk

1
Додано один із прикладів, як обробити автентифікацію користувача / клієнта, не знаючи попередньо " URL-адреси входу "
Akim

Ось ще дві приємні статті з авторами прикладів без громадянства для служб REST: blog.jdriven.com/2014/10/… technicalrex.com/2015/02/20/…
Володимир Рожков

41

TL; DR Вхід для кожного запиту не є обов'язковим компонентом для реалізації безпеки API, автентифікація є.

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

REST не диктує жодних правил безпеки, але найпоширенішою реалізацією на практиці є OAuth з тристоронній аутентифікацією (як ви вже згадували у своєму запитанні). Сам по собі немає входу, принаймні, не з кожним запитом API. З тристороннім аутентифікацією ви просто використовуєте маркери.

  1. Користувач схвалює клієнт API і надає дозвіл на запити у вигляді довгожилого маркерів
  2. Клієнт Api отримує короткочасний маркер, використовуючи довгожитель.
  3. Клієнт Api надсилає нетривалий маркер із кожним запитом.

Ця схема дає користувачеві можливість скасувати доступ у будь-який час. Практично всі загальнодоступні API RESTful, які я бачив, використовують OAuth для цього.

Я просто не думаю, що ви повинні ставити свою проблему (і питання) з точки зору входу, а краще думати про забезпечення API взагалі.

Для отримання додаткової інформації про автентифікацію API REST в цілому, ви можете переглянути такі ресурси:


Так, OAuth! Дуже відверта відповідь, має бути прийнятою відповіддю, імхо.
Левіт

26

Значна частина філософії REST полягає у використанні якомога більше стандартних функцій протоколу HTTP при розробці вашого API. Застосовуючи цю філософію до аутентифікації, клієнт та сервер використовували б стандартні функції аутентифікації HTTP в API.

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

Але для API REST, екран входу та файли cookie сеансу не є суворо необхідними, оскільки кожен запит може включати облікові дані, не впливаючи на людину; і якщо клієнт не співпрацює в будь-який час, 401може бути надіслана "несанкціонована" відповідь. RFC 2617 описує підтримку аутентифікації в HTTP.

TLS (HTTPS) також був би варіантом і дозволяв би аутентифікувати клієнта до сервера (і навпаки) у кожному запиті, перевіряючи відкритий ключ іншої сторони. Крім того, це забезпечує канал для отримання бонусу. Звичайно, для цього необхідний обмін клавіатурою до спілкування. (Зверніть увагу, мова йде саме про ідентифікацію / автентифікацію користувача за допомогою TLS. Захист каналу за допомогою TLS / Diffie-Hellman - це завжди хороша ідея, навіть якщо ви не ідентифікуєте користувача за його відкритим ключем.)

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


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

1
Щоразу, коли існує концепція користувачів, щось повинно переходити від клієнта до сервера, щоб визначити, який саме користувач. Маркер OAuth, безумовно, може слугувати тут "обліковими даними" замість фактичної комбінації користувача / пароля. Забезпечення каналу за допомогою TLS - це, безумовно, завжди добре, але це майже навряд чи. Навіть якщо ви використовуєте файл cookie, якийсь маркер все одно надсилається на сервер із кожним запитом, лише із заголовком файлу cookie замість заголовка автентифікації.
wberry

І якщо ви з будь-якої причини не використовуєте TLS або OAuth, чи надсилає користувача / пароль щоразу дійсно гірше, ніж надсилати лише один раз? Якщо зловмисник може отримати користувача / пароль, зловмисник, можливо, може також отримати cookie сеансу.
wberry

Різниця між файлами cookie та аутентифікаційним заголовком полягає в тому, що файли cookie завжди пов'язані з певним доменом. Це означає, що коли API отримує файл cookie, він знає, звідки він (він був написаний тим самим доменом раніше). Заголовком ви ніколи не знаєте, і вам доведеться реалізувати для цього конкретні перевірки. Загалом я згоден, вони обоє облікові дані, але я думаю, що передача облікових даних не є логіном. Вхід - це активна дія відкриття дверей. У разі трехсторонніх аутентифікацій буде лише перше схвалення клієнта.
Славо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.