Коли доцільно використовувати cookies, а коли tokens для авторизації?

Багато читав про авторизацію через сесії/куки, на своєму сайті створив саме таку авторизацію, не бачу в ній мінусів.

Тепер починаю читати за токени, точніше за реалізацію авторизації через токени. Поки що не розумію чим саме не підходять куки? Токени — це той же ідентифікатор, який треба шукати десь в БД...

Які я бачу зараз для себе можливі переваги токена перед куками:
1. авторизація тих клієнтів, які просто не мають механізму куків (тобто користувачі заходять не через веб-браузер);
2. в токенах можна зберігати більше інформації;
3. для токенів не потрібен захист від CSRF, бо вони не видаються клієнтом автоматично на кожен запит, як це відбувається із куками.

По першому пункту — хіба багато таких клієнтів, хіба не 99,9% користувачів використовують браузер?

По другому пункту — а нащо взагалі там зберігати щось окрім ідентифікаторів, по яким потім можна нарити більше інформації...

Хм, зараз подумав, що може можна при створенні токена записати основні права, зашифрувати записане, а потім, при запитах від користувачів, навіть не шукати інформацію в БД, а зразу зчитувати її з токена й довіряти їй без перевірки... хоча чи безпечно таке робити?

Оновлення від 2016-07-23 19:53
Спочатку пропустив лінк на специфікацію (подумав що сильно нудно її читати =), але зараз бачу, що вона досить чітко описує нащо потрібні, в даному випадку, так звані Bearer Token

The access token provides an abstraction, replacing different
   authorization constructs (e.g., username and password, assertion) for
   a single token understood by the resource server.  This abstraction
   enables issuing access tokens valid for a short time period, as well
   as removing the resource server's need to understand a wide range of
   authentication schemes.

     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

                     Figure 1: Abstract Protocol Flow

   The abstract OAuth 2.0 flow illustrated in Figure 1 describes the
   interaction between the client, resource owner, authorization server,
   and resource server (described in [RFC6749]).  The following two
   steps are specified within this document:

   (E)  The client requests the protected resource from the resource
        server and authenticates by presenting the access token.

   (F)  The resource server validates the access token, and if valid,
        serves the request.

   This document also imposes semantic requirements upon the access
   token returned in step (D).

Оновлення від 2016-07-25 00:20
Поки що зупинився на варіанті зашифрованих куків, в яких зберігається не лише ідентифікатор користувача, а і трохи більше інфи (раніше я зберігав дані сесії в БД): Using secure client-side sessions to build simple and scalable Node.JS applications

Оновлення від 2016-07-25 10:43
У підходу «зашифруємо куки, щоб не використовувати БД, і щоб було побільше, так би мовити, stateless» — є серйозний мінус якраз у тому таки stateless, бо якщо ви захочете комусь змінити роль/права/пароль, чи відправити когось у баню, то у вас не буде можливості це зробити аж поки старі куки не втратять свою актуальність. Це буде особливою проблемою, коли кукам автоматично продовжують термін актуальності.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Тепер починаю читати за токени, точніше за реалізацію авторизації через токени. Поки що не розумію чим саме не підходять куки?
Что бы понять разницу важно разобраться чем отличается Passive и Active аутентификация.

Passive предпочтитеный режим для веб-сайтов, когда фронт-енд и бек-енд сервиса находятся в рамках одного домена. В таком режиме Token используеться между браузером и Trusted сервером(например — Google+), дальше веб-сервер, который делегирует авторизацию Trusted серверу(например твой Node.js бекенд), получив этот токен от браузера клиента создает Session cookie и использует его в дальнейшем преобразовав набор личной информации от Trusted сервера в свой личный — например смапив email из Token’a на набор ролей находящийся на твоем бекенде, зашифровав и преобразов Token в Session cookie.

Active режим(речь идет о прямом контроле Token’a из js) использоваться должен как можно реже для HTML веба. Это целесообразно в случае, когда используеться кроссдоменное серверное Api, например когда твой js клиент должен напрямую общаться с Google Maps Api или если твой личный Nods.js Api хостится в другом домене и подрозумевающеся в сабже HTTPOnly cookies, использовать просто не представляеться возможным.

Есть 2 направления:

1. Положение сессии: client-side vs server-side
2. Способ доставки: cookie vs custom header (token).

У клиентской сессии основное преимущество — stateless server, не надо на сервере иметь сторадж для сессии. Основной же недостаток — неудобно сессиию инвалидировать и менять данные в ней.

Способы доставки: для куки важна CSRF-защита, но при этом есть плюс в том, что куки можно вешать только на одределенные поддомены или рутовые домены и ограничивать по пути, и браузер/http-клиент будет хендлить все за вас. У токенов плюс в том, что отдельно заморачиваться с CSRF не нужно. Но все запросы нужно делать через JS.

В 99% случаев дефолтный вариант: сессия на сервере, передается через куки — подойдет лучше всего.

А можно поподробнее о том что вы подразумеваете под сессией на клиенте и как вы делаете стейтлесс сервер?

При розробці SPA на Angular + Asp.Net Mvc (index.html) + Asp.WebApi (у якості data-серверу) також стикнувся із проблемою вибору.
Використання bearer-token на мою думку вносить суттєві незручності :
1) необхідність десь зберігати access_token (localStorage чи cookie)
2) Для того щоб зробити щось подібне до sliding session expiration необхідно використовувати refresh_token, який теж потрібно зберігати і турбуватись, щоб до нього не отримали доступ.

Рекомендую почитати ті лінки, які дав Олександр Устілов в попередньому коментарі.

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

Після того як JWT виконав свою «одноразову» місію, треба стартувати сесію тому користувачу, який надав цей токен, наче він щойно ввів пароль (спеціально призначений для конкретного сервісу).

Рекомендується використовувати старі-добрі куки, але зашифровані.

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

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

Отримавши токен досить зручно працювати із цими сервісами.

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

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

Якщо говорити про cookie vs tokens як механізми захисту ресурсу (аутентифікації) то ніщо не заважає реалізувати «не stateless» токени, а також бани за потреби.

Apache Cordova не зберігає куки між запусками. Тому там треба окремо зберігати токен десь (у LocalStorage наприклад).

Сookies є оптимальними. Але треба враховувати, що саме вони авторизують, та створювати куки для конкретного шляху. Тоді куки творяться для кожної дії свої, і нема потреби в головному ідентифікаторі щось шифрувати.

Через базу то є оптимальний шлях зберігання. Усе інше — великий ризик підробки. Тобто, ти сам маєш контролювати куки зі свого боку.

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

Основна рол токен-авторизації — робота через API. Це фактично те саме, що логін-пароль, але ним не є. Вигода в тому, що токен даєш ти сам, тобто він не буде 123456. А от отримати його можна за логіном та паролем, але з дуууже великим таймуатом із логіном та паролем, щоб завадити перебору. Наприклад, лише через годину після запиту надавати або надсилати по SMS, або робити обмежений термін дії.
Інакше кажучи, звичайне собі секретне слово, але яке можна отримати та відновити знаючи пароль. Ключова вигода перед паролем — те що окремий токен дає право на конкретну дію, на відміну від пароля який дає право на все. Якщо уведуть токен, але не уведуть пароль — це дозволить власнику побачити, що хтось користується його токеном.

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

Кукіс доцільно використовувати усюди, де вони підтримуються (браузер).
У токенів інше призначення. Токени використовуються коли кукіс недоступні. Найбільш поширений варіант: АПІ.

Зависит от задачи, как по мне, самый удобный вариант который как даст возможность к масштабированию так и не будет дергать бд на каждую проверку это иметь некий секретный ключ которым ты будешь шифровать токены во время их выдачи, ну и соответственно имея этот ключ на всех серверах ты достаточно быстро сможешь проверить строку пришедшую от клиента убедившись в том что он не пытался ее изменить или подделать. Если интересно больше, почитай про HMAC. Ну и клевый сайтик который тебе может помочь — jwt.io

Єдине що залишається мінусом в такому підході — якщо користувач захоче змінити пароль, то його буде не так і легко вилогінити з «усіх місць», куди він увійшов зі старим паролем.

Тобто якщо у користувача спочатку був слабкий пароль, наприклад, 123, і хтось це побачив, залогінився під ним. А потім користувач отямився і змінив свій пароль на щось по-серйозніше. І як тепер вгадати що «ось ця кука ще зі старим паролем, а ця — вже ні»?

Sessionid в куках тот же токен, есть разница в том как передовать токен, если через хедер, то это дает больше управляемости, если токен хранится в куках то юзать для вебклиентов его проще, однако гонять его все время автоматом не всегда желаемо

Токени — це той же ідентифікатор, який треба шукати десь в БД
JWT token не надо искать в БД. Он создается на сервере и шарится между request/response. В этом его плюс в сравнении с session ID, который при каждом запросе необходимо доставать из БД и сверять.
2. в токенах можна зберігати більше інформації;
Это может оказаться и минусом, поскольку может увеличить время запросов в связи с большим его размером.

Є думка, що куки сильніше б’ють по швидкодії у порівнянні з токенами, але в HTTP 2 ситуація покращиться.

Цікаво через що падає швидкодія, через додаткові пару кілобайт?

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

Якщо картинки, css і т.п. на іншому домені, то не вішаються здається.

це навантажує сервер додатковими операціями автентифікації
Мабуть так би було, якщо б картинки та стилі роздавав динамічний сервер. Насправді, якщо говорити за PHP, то при запитах статики, до PHP справа не доходить. Те саме можна сказати й за Node.js, якщо вона схована за якоюсь проксьою, наприклад, у вигляді nginx (слава Казахстану!).
хіба не 99,9% користувачів використовують браузер?
ви мене змусили задуматися.. )))
а нащо взагалі там зберігати щось окрім ідентифікаторів, по яким потім можна нарити більше інформації...
якщо це АПІ, комусь може бути влом, або неможливо «рити»
хоча чи безпечно таке робити?
це більше питання до шифрування, почитайте чи можливо зламати SHA1 алгоритм

Загалом, я б не парився протоколи типу OAuth, SAML, OpenID більше для атворизацій через АПІ використовуються. Для юзерів сайту свій вел цілком достатній..

Основна перевага токенів — стейтлес, я наприклад використовую JWT для рест сервісів.

Тобто ви в токенах зберігаєте просто більше інформації, ніж у куках — це ви маєте на увазі?

Так, в токені шифрується вся потрібна інформація.

Ок, а де, в такому разі, цей токен зберігається на клієнті, в localStorage?

в куках! бінго! ))) можливо, і в localStorage звичайно )
access token — це концепція/підхід до процесу авторизації, а куки — це зховище данних. ви порівнюєте 2 абсолютно різні речі. Якщо ви зараз в куках тримаєте інфу по юзеру в зашифрованому вигляді і юзаєте її для авторизації, то це той самий access token, реалізований вами як свій велосипед, а не згідно якоїсь специфікації (OAuth наприклад).. хіба ні?

Тут ось це мається на увазі docs.google.com/...CaZq9sTCGoaDojSdwp7I/edit
Нема потреби в сесії, авторизація потрібна лише для специфічних одинарних запитів — токени
Є потреба зберігати стан — кукі

Підписатись на коментарі