Аутентифікація, авторизація та управління сесіями в традиційних веб-програмах та API


75

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

Однак у програмі на основі API ця інформація не надсилається автоматично, тому, розробляючи API, я повинен перевірити себе, чи надходить запит від автентифікованого користувача, наприклад? Як це зазвичай робиться?


1
Сподіваюся, ви не розробляли свої попередні веб-програми, припускаючи, що браузер буде правильно керувати сеансом.

2
@bor, я не впевнений, чи правильно це зробив, але я впевнений, що це нормально. Раніше я використовував PHP, тому я щойно перевірив $_SESSION, чи не так? Поки що я знайшов, що це працює нормально. Здається, браузери оброблятимуть сеанс / файли cookie?
Jiew Meng

Відповіді:


122

Протокол HTTP не має статусу, кожен запит виконується окремо і виконується в окремому контексті.

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

Печиво

У типовому випадку браузер-сервер; браузер управляє списком пар ключ / значення, відомим як cookies, для кожного домену:

  • Файлами cookie може керувати сервер (створювати / модифікувати / видаляти) за допомогою Set-Cookieзаголовка відповіді HTTP.
  • До файлів cookie може отримати доступ сервер (читати), проаналізувавши Cookieзаголовок HTTP-запиту.

Мови / фреймворки, орієнтовані на Інтернет, надають функції для роботи з файлами cookie на більш високому рівні, наприклад, PHP забезпечує setcookie/$_COOKIE пише / читає файли cookie.

Сесії

Повернення до сеансів. У типовому випадку браузер-сервер (знову ж таки) управління сеансами на стороні сервера використовує переваги управління файлами cookie на стороні клієнта. Управління сеансом PHP встановлює файл cookie ідентифікатора сеансу та використовує його для ідентифікації наступних запитів.

API веб-додатків?

Тепер повернемося до вашого запитання; оскільки ви будете відповідальними за розробку API та його документування, впровадження буде вашим рішенням. Ви в основному повинні

  1. дайте клієнту ідентифікатор, будь то за допомогою Set-Cookieзаголовка відповіді HTTP, всередині тіла відповіді (відповідь аутентифікації XML / JSON).
  2. мають механізм підтримки асоціації ідентифікатор / клієнт. наприклад таблиця бази даних, яка пов'язує ідентифікатор 00112233445566778899aabbccddeeffз клієнтом / користувачем #1337 .
  3. нехай клієнт повторно відправляє ідентифікатор, надісланий йому за номером (1.) у всіх наступних запитах, будь то Cookieзаголовок HTTP- запиту, ?sid=00112233445566778899aabbccddeeffпараметр (*).
  4. шукайте отриманий ідентифікатор, використовуючи механізм у (2.), перевірте, чи є дійсною автентифікацією, і має право виконувати запитувану операцію, а потім продовжуйте операцію від імені користувача, що авторизується.

Звичайно, ви можете базуватися на існуючій інфраструктурі, ви можете використовувати управління сеансами PHP (яке б подбало про 1./2 і частину автентифікації 4.) у вашому додатку і вимагати, щоб реалізація файлів cookie виконувалась на стороні клієнта подбав би про 3.), а потім ви виконуєте решту логіки свого додатка.


(*) Кожен підхід має мінуси і плюси, наприклад, використання параметра запиту GET простіше реалізувати, але це може мати наслідки для безпеки, оскільки запити GET реєструються. Вам слід використовувати https для критичних (усіх?) Додатків.


2
Ідеальна відповідь! Дякую
Суворий Даттані

Щоб додати більше інформації для будь-якого читача, одним з найважливіших аспектів управління сеансами є безпека. У цьому є багато аспектів: які типи маркерів використовувати, як працюватиме відкликання, довжина токена та ентропія та захист від різноманітних атак. Також у випадку, якщо маркери дійсно вкрадені (що теоретично завжди можливо), як ми можемо виявити таку активність (див. Обертання маркерів оновлення в RFC 6819)? Оскільки мені неможливо пояснити всі свої думки в цьому розділі коментарів, ви можете прочитати більше про цю тему тут: medium.com/@supertokens.io/ee5245e6bdad
Rishabh

47

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

session_start();  // Will create a cookie named PHPSESSID with the session token

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

// If username and password match, you can just save the user id on the session
$_SESSION['userID'] = 123;

Тепер ви можете перевірити, чи аутентифіковано користувача чи ні:

if ($_SESSION['userID'])
    echo 'user is authenticated';
else
    echo 'user isn't authenticated';       

Якщо ви хочете, ви можете створити сеанс лише для автентифікованого користувача:

if (verifyAccountInformation($user,$pass)){ // Check user credentials
    // Will create a cookie named PHPSESSID with the session token
    session_start();
    $_SESSION['userID'] = 123;
}

9

Для автентичних користувачів існує безліч способів як для веб-додатків, так і для API. Існує кілька стандартів, або ви можете написати власну власну авторизацію / та автентифікацію. Я хотів би вказати на різницю між авторизацією та автентифікацією. По-перше, програма повинна аутентифікувати користувача (або клієнта API), з якого надходить запит. Після аутентифікації користувача на основі ідентифікації користувача програма повинна визначити, який аутентифікований користувач має дозвіл на виконання певної програми (авторизації). Для більшості традиційних веб-додатків у моделі безпеки немає тонкої деталізації, тому, як тільки користувач проходить автентифікацію, він у більшості випадків також уповноважений виконувати певні дії. Однак ці дві концепції (автентифікація та авторизація) повинні бути як дві різні логічні операції.

Більше того, в класичних веб-додатках, після того, як користувач пройшов автентифікацію та авторизацію (переважно шляхом пошуку пари ім’я користувача / пароль у базі даних), інформація про авторизацію та ідентифікацію записується у сховище сеансів. Сховище сеансів не повинно бути на стороні сервера, як передбачається більшістю відповідей вище, воно також може зберігатися в файлі cookie на стороні клієнта, зашифрованому в більшості випадків. Наприклад, платформа PHP CodeIgniter робить це за замовчуванням. Існує ряд механізмів захисту сеансу на стороні клієнта, і я не бачу такий спосіб зберігання даних сеансу менш захищеним, ніж зберігання sessionId, який потім шукається в сховищі сесій на стороні сервера. Крім того, зберігання сеансу на стороні клієнта досить зручно в розподіленому середовищі,

Більше того, автентифікація за допомогою простої пари користувач-пароль не обов’язково повинна здійснюватися за допомогою спеціального коду, який шукає відповідний запис користувача у базі даних. Існує, наприклад, базовий протокол автентифікації або дайджест-аутентифікація . У власному програмному забезпеченні, такому як платформа Windows, є також способи автентифікації користувачів через, наприклад, ActiveDirectory

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

У конкретному випадку використання, при розробці веб-служби, яка використовує SOAP як протокол, існує також розширення WS-Security для протоколу SOAP.

З урахуванням усього сказаного, я б сказав, що відповіді на наступне питання вводять процедуру прийняття рішення щодо вибору механізму авторизації / автентифікації для WebApi:

1) Яка цільова аудиторія, чи є вона загальнодоступною чи лише для зареєстрованих (платних) членів?
2) Чи він запущений, або * NIX, або платформа MS
3) Яка кількість користувачів очікується
4) Скільки стосується API конфіденційних даних (сильніші та слабші механізми автентифікації)
5) Чи існує якась служба єдиного входу, якою ви могли б скористатися

.. та багато іншого.

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


1

Якщо APP на основі API є Клієнтом, тоді API повинен мати можливість отримувати / читати файли cookie з потоку відповідей сервера та зберігати їх. Для автоматичного додавання файлів cookie під час підготовки об'єкта запиту для того самого сервера / URL-адреси. Якщо він недоступний, ідентифікатор сеансу отримати не вдається.


1

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

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

Існує безліч інших механізмів автентифікації для API на основі HTTP, HTTP basic / digest, щоб назвати пару, і звичайно всюдисущий o-auth, який розроблений спеціально для цих речей, якщо я не помиляюся. Файли cookie не підтримуються, облікові дані є частиною кожного обміну (у цьому я впевнений).

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


1

Я б запропонував вам надсилати якийсь маркер із кожним запитом.

Залежно від сервера та сервісу, це може бути параметр JSESSIONID у вашому запиті GET / POST або щось зріле, як SAML у SOAP через HTTP у вашому запиті веб-служби.

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