Аутентифікація API REST


181

Я будую додаток, який буде розміщений на сервері. Я хочу створити API для програми, щоб полегшити взаємодію з будь-якою платформою (Web App, Mobile App). Що я не розумію, це те, що при використанні API REST, як ми автентифікуємо користувача.

Наприклад, коли користувач увійшов у систему, а потім хоче створити тему форуму. Як я дізнаюся, що користувач уже увійшов до системи?


4
Ви, ймовірно, повинні шукати "REST аутентифікацію" тут. Це було висвітлено у багатьох інших питаннях.
Брайан Келлі

10
Коротше кажучи, дозвольте клієнту надсилати ім’я користувача та пароль з кожним запитом за допомогою HTTP Basic Auth (через SSL!) Або автентифікувати один раз, щоб клієнт мав аутентифікований сеанс, який закінчиться через деякий період бездіяльності (або, проте ви вирішите замінити обробка сеансу вашого веб-бази). Зазначений сеанс може бути збережений у файлі cookie або параметр, що передається з кожним запитом (наприклад, JSESSIONID на землі Java).
опять


@opyate з точки зору безпеки, це не дуже гарна ідея обробляти сеанс за допомогою файлів cookie у випадку REST API, оскільки зловмисники можуть надсилати запити без згоди користувача. Краще включити хеш-сесію або маркер сеансу до заголовка HTTP (наприклад, Авторизація).
s3v3n

1
@ s3v3n Виправте мене, якщо я помиляюся, але і ваші, і мої пропозиції - це просто різні способи використання заголовка + локального комбінаційного накопичувача, щоб здійснити те саме. Це Authorizationзаголовок + напр., Місцевий веб-переглядачStorage VS Cookie+ стандартне зберігання файлів cookie.
опіят

Відповіді:


72

Ви можете використовувати HTTP Basic або Digest Authentication. Ви можете надійно автентифікувати користувачів за допомогою SSL у верхній частині, проте це трохи сповільнює API.

  • Основна автентифікація - використовує кодування Base64 для імені користувача та пароля
  • Дайджест аутентифікації - хеширує ім’я користувача та пароль, перш ніж надсилати їх по мережі.

OAuth - найкраще, що можна отримати. Переваги, які надає oAuth, - це відкликаний або втрачений термін дії. Дивіться наступні відомості про те, як реалізувати: Робоче посилання з коментарів: https://www.ida.liu.se/~TDP024/labs/hmacarticle.pdf


4
Прочитайте, будь ласка, це питання та відповідь, яку надав Лес Хейзелвуд (автор «Apache Shiro»).
Justin.hughey

1
Корисне посилання про те, як Twitter захищає API REST: Безпека API REST API
WildDev

Оскільки це прийнята відповідь, я вважаю, що важливо зазначити, що ви також можете використовувати Digest аутентифікацію. Читайте про відмінності між базисними і Digest авторизаций тут: stackoverflow.com/questions/9534602 / ...
Рейє Roded

116

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

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

Перевірте, як Amazon AWS робить аутентифікацію. Це прекрасний приклад "передачі долара" з одного API в інший.

* Я думав додати деяку практичну відповідь до своєї попередньої відповіді. Спробуйте Apache Shiro (або будь-яку бібліотеку аутентифікації / авторизації). Підсумок, намагайтеся уникати спеціального кодування. Після інтеграції улюбленої бібліотеки (я використовую Apache Shiro, btw), ви можете зробити наступне:

  1. Створіть API входу / виходу, як: /api/v1/loginіapi/v1/logout
  2. У цих API для входу та виходу виконайте аутентифікацію з вашим магазином користувачів
  3. Результат - це маркер (як правило, JSESSIONID), який надсилається назад клієнту (веб, мобільний, будь-який інший)
  4. З цього моменту всі наступні дзвінки, здійснені вашим клієнтом, включатимуть цей маркер
  5. Скажімо, наступний дзвінок зроблений в API, який називається /api/v1/findUser
  6. Перше, що цей код API зробить - це перевірити маркер ("чи справжній користувач перевірений?")
  7. Якщо відповідь повернеться як "НІ", ви повернете на клієнта статус HTTP 401. Нехай вони впораються.
  8. Якщо відповідь ТАК, перейдіть до повернення запитуваного Користувача

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


Отже, те, що ви описуєте, це по суті файли cookie сесії, правда?
LordOfThePigs

так, але сеанс "підтримується" у двох різних місцях. Один на сервері API, інший у браузері. Відповідь JSON (або що завгодно) назад до успішного входу в браузер повинен повідомити браузер ідентифікатор сеансу на сервері API. Ці сеанси незалежно керуються відповідними агентами.
Кінгз

11
Я вважаю, що Кінгз намагався донести думку про те, що механізм підтримки сесії навмисно розпливчастий. Сесійне cookie - лише одна реалізація цього механізму.
Justin.hughey

2
@Kingz, а як щодо безпеки в цьому рішенні, наприклад, якщо якийсь хакер обнюхає посилання на session_id і почне надсилати запити, який вміст виправляє session_id? Ми можемо вирішити це, додавши ssl до підключення до сервера, а як щодо клієнтів?
Ахмад Саміло

1
як запобігти викрадення сеансу у випадку "людина в середині"?
m0z4rt

38
  1. Використовуйте HTTP Basic Auth для аутентифікації клієнтів, але трактуйте ім’я користувача / пароль лише як тимчасовий маркер сеансу .

    Маркер сеансу - це лише заголовок, приєднаний до кожного HTTP-запиту, наприклад: Authorization: Basic Ym9ic2Vzc2lvbjE6czNjcmV0

    рядок Ym9ic2Vzc2lvbjE6czNjcmV0 вище - це лише рядок "bobsession1: s3cret" (який є ім'ям користувача / паролем), закодований в Base64.

  2. Щоб отримати тимчасовий маркер сеансу вище, надайте функцію API (наприклад:), http://mycompany.com/apiv1/loginяка приймає головне ім'я користувача та головний пароль як вхід, створює тимчасове ім'я користувача / пароль HTTP Basic Auth на стороні сервера та повертає маркер (наприклад: Ym9ic2Vzc2lvbjE6czNjcmV0). Це ім'я користувача / пароль має бути тимчасовим, воно має закінчитися через 20 хв.

  3. Для додаткової безпеки переконайтеся, що ваша послуга REST обслуговується через HTTPS, щоб інформація не передавалася в простому тексті

Якщо ви користуєтесь Java, бібліотека Spring Security надає хорошу підтримку для впровадження вищевказаного методу


1
Чому він повинен закінчуватися через 20 хв? що робити, якщо це веб-сайт на зразок фейсбуку, що логін є, поки користувач не вийде?
Dejell

1
@dejel Я був за припущенням, що "сесія" носить тимчасовий характер. Зазвичай це закінчується, якщо користувач працює в режимі
очікування

Для чого Base64? Ви можете просто повернути тимчасовий пароль. В обох випадках важливо, що цей тимчасовий пароль є надійним. Перевірте security.stackexchange.com/a/19686/72945
e18r

7

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

Це спростить розробку клієнтських додатків для вашого API з веб-програми чи мобільного.

Сподіваюся, це допоможе вам.


2
Прочитайте, будь ласка, це запитання та відповідь Лес Хейзелвуд (автор «Apache Shiro»).
Justin.hughey

0

Я використовував аутентифікацію JWT. Працює чудово в моєму застосуванні.

Існує метод аутентифікації, який потребує облікових даних користувачів. Цей метод перевіряє облікові дані та повертає маркер доступу у випадку успіху.

Цей маркер повинен бути надісланий кожному другому методу мого веб-API у заголовку запиту.

Це досить просто в реалізації та дуже легко тестувати.

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