Забыли пароль?
Запросите новый здесь.

Автор темы: Zaxap
ID темы: 3032
Информация:
Тема содержит 19 сообщения, была просмотрена 923 раз.  Имеются прикрепленные файлы.
Просмотр темы
PHP-Fusion Russia » Разное » Разное
 Распечатать тему
[вопрос не по PHP-Fusion] Верно ли я понимаю принципы Hawk Auth?
Zaxap
Добрый день, ребята. Перечитал все, что смог о данной ерунде, но остались вопросы. Не имею никакого понимания, где мне действительно ответят, поэтому осмелюсь написать здесь.
В разных вариантах реализации, в разных примерах, я видел различные обозначения одного и того же: где-то MAC называется hash'ем, либо же hash - какая-то другая хэшированная строка, secret где-то key. И другие разнообразные вещи, приводящие к путанице.
Далее опишу, как я понимаю спецификацию.

Вот что мы имеем:
Загрузить источник  GeSHi: PHP
  1. $keyId = "dh37fgj492je";
  2. $key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn";
  3. $algo = "hmac sha256";
  4. $hash = "6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=";
Добавлено за 0.029 секунд, используя GeSHi 1.0.8.10


Когда мы получили эти данные? Как я понял, мы можем получить их при авторизации; данные, записанные в базу при авторизации. Поправьте, если неверно. Далее мы сохраняем эти данные в Cookies. Но все ли данные или только $keyId, $key и $algo?

Далее, при при попытке получения, допустим, информации о пользователе (о "нас"), (допустим, из API) мы отправляем заголовок, созданный на основе этих данных, записанных в Cookie.

Следом передаем этот заголовок на адрес, информацию с которого хотим получить (в данном случае это какой-нибудь https://www.example.com/api/user/29487), там "разбираем" их (сверяем с данными сервера), получаем ответ.

Вопросы.
- Какие данные должны храниться у пользователя в Cookie (или LocalStorage), а какие -- только на стороне сервера?
- Какие данные из хранимых являются временными, а какие хранятся какое-то время, аналогично идентификатору сессии?
- Должно ли быть, или обязательно ли должно быть хранилище данных сессии, или же можно сохранять информацию в полях таблицы пользователя?

Надеюсь на ответ с указанием на ошибки в моем понимании теории.
Заранее благодарю.


Зло не дремлет, а я добрый...
 
ovas
Не знаю насчёт API, но на сервере есть папка для хранения мусора .cagefs, она лимитируется через maincore.php
Строчка 50; 52
ini_set('session.gc_maxlifetime', 21600); // 6 hours
// Session cookie life time
ini_set('session.cookie_lifetime', 21600); // 6 hours
Это ограничение чистит автоматически мусор на сервере в папке .cagefs,
На девятке это уже пишется в таблицу и можно этот мусор чистить уже через админку

picusha.net/img/2019-01/13/5krwzvbr3r9ys4o1mdh283mga.jpg

А что в этом мусоре, хрен его знаетag

x1
 
Web
Rush
Зачем тебе понадобилась эта древняя мертворожденная балалайка? Возьми jwt, плюс минус те же яйца только проще и намного актуальнее.

В детали не вникал, но условно по этим отрывочным данным https://alexbilbi...on-scheme/ и https://github.co...c/Hawk.php
1) тебе некий сервер выдает id, secret и говорит какой алгоритм (sha256) (у себя хранит пару id-secret)
2) ты берешь этот id, secret, добавляешь другие параметры вроде timestamp, method, host, port и прочей ненужное пое*ени, собираешь строку нужного формата и хешируешь это все нужным алгоритмом (sha256)
3) собираешь заголовок вида Authorization: Hawk id= ts= mac= и шлешь на сервер
4) сервер по id который ты прислал берет из базы secret который тебе раньше выдал, берет из запроса недостающие аргументы вроде method, host, port и прочую ненужную пое*бень, собирает заново этот хеш и сверяет с тем что ты прислал в mac.

Ну и как бы все. Ничего сверхсекьюрного или нового тут нету, обычная пара публичный-секретный ключ. Причем для браузерных приложений типа SPA и т.д. эта балалайка не годится абсолютно, я авторизацию на сайте с помощью этой балалайки я плохо себе представляю. Она позиционируется как замена oauth2 (хотя 7 лет прошло и oauth2 до сих пор на коне).
Как итог - для браузерных приложений - JWT, для сервер-сервер - oauth2.


x1
 
Web
Zaxap
Rush, я нашел для себя Hawk, как метод аутентификации, обеспечивающий защиту от атак по времени.

Минус jwt в том, что мне в итоге все равно придется действовать по одному из методов:
- Использовать хранилище сессий актуальных jwt-токенов
- Создавать jwt-токены (шифровать) на основе каких-либо параметров в таблице пользователя (допустим, создадим поле secret), заменяя эти параметры после запроса с помощью этого токена.

Создание хранилища сессий полностью убивает предназначение jwt-токенов, а именно, автономность, что ли.
Второй метод не позволит пользователям нормально логиниться с разных устройств..

И, насколько я прочитал, Hawk обеспечивает защиту от атак по времени.

Из всего, что прочитал по jwt, я извлек, что этот метод слабо подходит для авторизации (не подходит, видимо). И для этого стоит использовать сессии. Или рекомендации по созданию хранилища jwt-токенов.

Ваш совет -- все-таки использовать Oauth?
А если речь идет о серверной части, как RestAPI-server и клиентской, как SPA, что лучше использовать?
Только Oauth2?Или все-таки пихать в сессии для SPA, что находится на том же домене, а для приложения пилить Oauth? Не понимаю.
Я немного утонул в тонне всяких новомодных штук.

Знакомых веб-программистов у меня нет. Тем более, таких, которые бы пояснили, почему та или иная моя идея не особо жизнеспособна, и предложили бы свой вариант решения проблемы, опять таки, пояснив, у меня нет. Так что я испытываю некоторые проблемы со всем этим делом. Статьи часто противоречивы, и они написаны людьми, которым также свойственно ошибаться.


Изменил(а) Zaxap, 14.01.2019 18:14
Зло не дремлет, а я добрый...
 
Rush
У тебя по-моему какая-то паранойя

Если атака по времени это вот это https://ru.wikipe...по_времени, то мне лично кажется что в условиях реального приложения это как-то очень маловероятно осуществимо)

Если у тебя SPA - то использовать hawk я бы не советовал, тупо негде на клиенте хранить секретный ключ. Ты же не зашьешь его в код потому что это глупо)
В rfc jwt конечно же не говорилось про то чтобы хранить токены на сервере с целью инвалидации и т.д. Вот здесь например https://toster.ru...er_1249550 интересная беседа про то как человек добавил к jwt refresh токены и хранил это все в базе тем самым превратил jwt в обычный oauth, только где токен по другому составлен. И на мой взгляд нету в этом большого практического смысла, проще сразу использовать oauth и пилить своих костылей)

Лично я бы делал все проще и не усложнял бы без необходимости:
- простейшее SPA (когда все висит на одном домене, представляет из себя монолитное приложение и не планирует скейлится) - обычная авторизация на сессиях-куках
- простое SPA (когда уже фронтенд и бэкенд - два разных standalone приложения) - jwt без хранения чего-либо (это не супер безопасно, но излишняя безопасность в 99% просто не нужна)
- посложнее SPA (если тебе нужно инвалидировать выдаваемые токены, иметь различные scope и т.д.) - oauth2 со схемой например password grant (https://www.oauth.com/oauth2-servers/access-tokens/password-grant/ - в этой схеме не нужно танцев с редиректами, токен выдается только по логину и паролю что идеально для spa или мобильных приложений и является самым простым решением) (либо использовать рекомендуемую схему для SPA с code grant type https://www.oauth.com/oauth2-servers/single-page-apps/ которая например используется у того же vk)


 
Web
Zaxap
Rush, да, паранойя от незнания и незнания реальной сиутации в том числе. Я давно уже ничего не делал в продакшн, тем более, с бэк-эндом.

Из ваших слов делаю вывод: лучше всего будет сделать авторизацию на сессиях и куках в моей ситуации.
И неважно, что back-end выдает RestfulAPI-ответы, а front-end -- это SPA на React или Vue (или еще чем-нибудь).
А для внешнего приложения, завязанного на том же API, запилить, Oauth-токены.
Хм. Спасибо за пояснение! И огромное спасибо за ссылки.


Тогда еще вопрос: имеет ли смысл данная система авторизации?
Спойлер


Изменил(а) Zaxap, 15.01.2019 11:07
Зло не дремлет, а я добрый...
 
Rush
Для JWT обычно не практикуют по ключу на пользователя, обычно это один ключ на всех. И если ты его поменяешь, то все пользователи разлогинятся. Хотя тут вариантов много, можно извращаться сколько фантазии хватит)


 
Web
Zaxap
Rush, а будет от этого хоть какой-нибудь толк? Или постоянное "дерганье" сессий соизмеримо с постоянным вычислением валидности JWT-токенов?

Zaxap присоединено следующее:изображение:
auth_scheme.png

Зло не дремлет, а я добрый...
 
Rush
https://i.imgur.c...pl9ELd.png

1. Когда ты пересоздаешь секрет - все пользователи разлогиниваются ab
2. Если у тебя авторизация на сессиях то зачем тебе еще нужен jwt? Тут мне кажется либо одно, либо второе. Отправил логин-пароль - получил токен, сохранил его в локал сторадж и отправляешь с каждым аякс запросом. Либо если сессии - отправил логин-пароль, сервер завел тебе сессию, повесил куку и все, ты уже авторизован на сайте, ничего даже слать дополнительно не надо.
3. Если jwt токен истек то пользователя надо отправлять на логин форму, никаких новых токенов по истекшему токену не выдается. Раньше были схемы что когда сервер видит что до истечения токена осталось скажем н минут - при аякс запросе генерится новый токен и добавляется в какой-нибудь заголовок, клиент забирает из ответа и обновляет у себя. Но это тоже субъективно. Но без рефреш токена тут либо так, либо форма логина.


 
Web
Zaxap
Rush, да, для этого и нужна "Сессия" -- замена Refresh-токену.
Цикл от этого и начинается с проверки, валиден ли JWT-токен.
При каждом "разлогинивании" пользователя, по истечении JWT-токена, новые права запрашиваются из сессии, создается новый JWT-токен.
Далее обращение к сессии не происходит до пересоздания SECRET-ключа.
Таким образом я убираю нагрузку с Хранилища сессий или с Базы данных на момент действия JWT-токена.
Другой вопрос -- будет ли возможная нагрузка на ту же БД (или Хранилище сессий) соизмерима с нагрузкой от постоянной дешифровке JWT-токена на сервере?

Таким образом, создавать хранилище Refresh-токенов или хранилище валидных JWT-токенов не нужно (это вообще странность, по-мне).
Сессии вполне себе можно доверять.
Решения кроме Сессии или записи в Таблице пользователя, к которой необходимо будет периодически обращаться, я не придумал.


Изменил(а) Zaxap, 16.01.2019 09:58
Зло не дремлет, а я добрый...
 
Rush
Мне кажется в этой схеме jwt абсолютно излишен и не нужен.


 
Web
Zaxap
Rush, но тогда будет куда меньше обращений к базе в том же закрытом чате, быстрее отклик. Или же я не прав, и выхлопа никакого не будет, излишняя паранойя?


Зло не дремлет, а я добрый...
 
Rush
Не знаю про какие закрытые чаты ты говоришь и как у тебя там все реализовано, но на количество к запросов в базе это наверное никак не должно влиять. Тут один запрос на получения профиля пользователя по primary key в обоих случаях


 
Web
Zaxap
Rush, про любые чаты, в которых необходима авторизация.

В обычном случае происходит следующее:
1. Пользователь пытается создать новость.
2. Из таблицы пользователя берутся данные о его правах.
3. Создание разрешается с последующей записью в таблицу с новостями, либо отклоняется.

В моей схеме:
1. Пользователь пытается создать новость.
2. Из JWT-токена берутся данные о его правах.
3. Создание разрешается с последующей записью в таблицу с новостями, либо отклоняется.
Если JWT-токен неверный (создан с помощью устаревшего ключа), из таблицы пользователя берутся данные о его правах и записываются в новый JWT-токен.

Во втором случае не происходит постоянного обращения к таблице пользователя при подобных операциях.
Или все это излишне?


Зло не дремлет, а я добрый...
 
Rush
> 2. Из JWT-токена берутся данные о его правах.

из jwt токена ты можешь только получить основную инфу о юзере, например его идентификатор, при каких-то действиях на сервере тебе все равно нужно проверять может это пользователь сделать или нет. Хранить роли в токене можно лишь только с целью использования на фронте, т.е. показать кнопку отправить сообщение или нет к примеру. А основная задача сервера - не верить всему что приходит с клиента и все перепроверять)


 
Web
Zaxap
Rush, а почему нельзя доверять JWT-токену, если он закодирован при помощи достаточно "сильной соли", обновляющейся каждые N минут?


Зло не дремлет, а я добрый...
 
Rush
Потому что это неправильно. Ты не можешь быть на 100% уверен что ты выдал этот токен


 
Web
Zaxap
Rush, для этого я и перезагружаю каждый раз ключ шифрования. Или же это все равно не обеспечивает безопасность?

Я все равно считаю, что в простом проекте вроде того же онлайн-чата (считаю этот пример наиболее подходящим) данная система авторизации более чем приемлема.
Особенно если это будет что-то, крутящееся на ржавом ведре. Так ведь?


Изменил(а) Zaxap, 17.01.2019 10:47
Зло не дремлет, а я добрый...
 
Rush


 
Web

Поделиться этой темой
Социальные закладки: Vkontakte Odnoklassniki Mail.ru Facebook Google Tweet This
URL:
BBcode:
HTML:

Перейти на форум: