Всего 125 351 комментарий

Александр Мельник
14 мая 2022, 08:49
0
а вот еще хотелось бы мне подискутировать на затронутую мной же тему jwt токенов.
Кто скажет, почему payload не шифруется а лишь кодируется? В чем сокральный смысл использовать base64, который очень просто раскодировать и узнать данные?
Как я понимаю жизненный цикл access токена:
— сервер авторизации и сервер, на котором мы хотим обратиться знают один и тот же ключ, при помощи которого создана сигнатура в токене.
— мы при каждом запросе мы передаем этот токен на сервер. Сервер (в каком то midleware ну или как там разработчик сделает) берет payload и кодирует тем же ключем. И сравнивает сигнатуру которую он получил с той, что пришла в токене.
— если сигнатуры совпали это говорит о том, что запрос пришел от того, кто обращался на наш сервис авторизации и смог получить токен.
— НО мы ничего еще не знаем о самом клиенте. Кто именно делает запрос. А если у нас есть деление на какие то роли и не каждый кто просто получил токен имеет пользоваться всем. Или же мы ведем логирование запросов и нам нужен хотя бы id пользователя. Тоесть как ни крути, там же на этапе аутентификации нужно раскодировать payload и получить исходные данные, чтобы получить например объект с перечислением ролей и определить, допустима ли тому, кто отправил запрос, операция удаления пользователей.
— тоесть сам факт проверки сигнатуры не дает еще полной картины, раскодировать payload прийдется каждый раз.
— и в такой схеме действительно возникает проблема. Если токен украли, то пока он «жив» вор может пользоваться им и нанести вред.

Теперь собственно моя идея.
— раз нам все равно на каждый запрос нужно раскодировать payload токена, то почему не включить в него информацию, которая позволит решить проблему с угоном токена. Что-то что будет служить дополнительной защитой.
— к примеру ip адрес того, кто обратился на сервер авторизации и получил токен. Добавим ip в payload и на этапе аутентификации на своем сервере, сравниваем, а тот ip что пришел в токене и реальный ip который мы получаем из самого запроса — совпадают ли?
— так же в случае если мы говорим про применение jwt не для общения с api, а для использования в браузере, в токен можно добавить user-agent, который даст информацию о том, с какой операционной системы и с какого браузера был получен токен. И есть еще масса уникальной информации, которую можно получить и использовать для идентификации того или иного устройства.
— что это нам дает. Решение классической проблемы — угнали токен и до конца его жизни могут пользоваться. Теперь даже в случае угона токена, он не будет принят на сервере, на который мы стучимся, потому что точно не пройдет проверку ip и скорее всего не пройдет проверку user-agent.
— нельзя конечно полностью утверждать, что это 100 процентная защита от угона токена, вернее от возможности его использование вором, но это уже сильно усложнит жизнь вору. Насколько я знаю, подделать ip с которого отправляешь свой запрос на какой то конкретный (а чтобы токен прошел валидацию нужен именно конкретный), не так уж и просто. Но предположим что супер хакеры умеют.
— и мы возвращаемся к моему вопросу — почему payload просто кодируют, а не шифруют? Тот кто украл токен имеет прямой доступ к информации, пусть даже и не знает ключа шифрования, при помощи которого была создана сигнатура. В моей схеме, вор получив токен сразу же использует его чтобы получить доступ к нашему сервису. Не выходит, банально потому что его ip не совпадает с тем с которого он совершает запрос.
— если payload только закодирован base64 вор получает с него данные и видит, что в данных содержится и ip. И начинает как то решать эту проблему и искать способ подделать свой ip на этот конкретный. Если время жизни токена невелико то и времени для поиска решения не много. Но ведь можно не дать ему и этого шанса. Не будем кодировать, будем шифровать payload. Мы уже используем один ключ, который создает сигнатуру. Можем использовать его или завести еще один. Чистые данные шифруем при помощи ключа. получаем payload. payload шифруем при помощи ключа — получаем сигнатуру. Складываем их вместе, получаем довольно безопасный токен.
— теперь даже если украсть токен, то «тупое» его использование ничего не даст и дело не во времени его жизни, а в несовпадении данных из токена с реальными данными запроса. И посмотреть что лежит в payload хакер тоже не может, данные не закодированы, а зашифрованы и не имея ключа их не расшифровать.

Такой подход, как мне кажется, даже позволит завести в свой системе авторизации пару приятных плюшек:
— автопродление токена. Поскольку у нас теперь токен содержит дополнительные уровни защиты, то в зависимости от уровня безопасности всего проекта, можно облегчить жизнь нашим пользователем. Если токен пришел на сервер и в нем все идеально, кроме времени жизни (он уже протух), можно не отправлять пользователя на повторную авторизацию руками, а самим сделать запрос на наш сервис авторизации, передать туда данные из payload и получить новый токен. Никто ведь из людей не любит очень часто вводить пароль. Но это для проектов, чей уровень безопасности не высок.
— можно вести статистику успешных и неуспешных использований токена и на основании ее изменять время жизни токена для конкретного пользователя. Если видим, что присылается токен с зашитым внутрь одним ip а запрос приходит с другого ip, то в следующий раз этому клиенты выдадим токен не на 30 минут, а на 5 минут.
Василий Наумкин
14 мая 2022, 05:58
+2
Так можно сделать только если на сервере всего один сайт, который займёт 80 порт.

А если сайтов 2 или более — то нужен Nginx или Apache2, которые будут разруливать запросы.

Очевидно, что на публичных хостингах тебе просто придётся работать с одним из них.
Роман
13 мая 2022, 21:55
+1
Можно через консоль или через логи =).
$_modx->log(1, print_r([2,3,4,5], 1));
Роман
13 мая 2022, 21:52
+1
Не важно, будет этим кто-то пользоваться или нет. Самое главное, что есть какие-то реальные задачи и их решения. Не так много, кто готов поделиться рабочей схемой, даже самой простой.
Александр Мельник
13 мая 2022, 19:49
0
nginx у нас это прокси сервер, nitro это веб сервер. Причем я почитал документацию, он умеет отдавать и статику тоже.
Зачем использовать nginx, почему не настроить nitro на 80 порт и слушать запросы напрямую на нем?
Василий Наумкин
13 мая 2022, 19:41
0
Да что ты говоришь.

Тут вот люди даже Hello World пока не могут вывести, а потом начнутся вопросы про реактивность, асинхронность и Vuex.

Для того, чтобы это стало простым и клёвым, нужно взойти на определённую высоту. После этого — да, оно всё просто. А вот MODX и WP наоборот кажутся очень сложными и неудобными, вот такой парадокс.

Насчёт ассемблера… Ну как покажешь веб-сайт на ассемблере, тогда и продолжим сравнения.
Артур Шевченко
13 мая 2022, 19:35
+2
Вот тут написано про как получить файлы. А дебажить можно выводом в журнал ошибок $modx->log(1, 'Message');
Александр Мельник
13 мая 2022, 19:34
0
А Nuxt и прочее Node.js это уже для серьёзных специалистов.
с этим наверное не соглашусь. Наоборот, современная разработка становится все более высокоуровневой, мы оперируем сплошными абстракциями, все дальше уходя от компьютера как железа. Программировать становится все проще, синтаксис все сахарнее. Скоро доживем до того, что программирование будет типа
const site = new Site();
site->getWonderfullShop('no cart please');
Поэтому не соглашусь, что nodejs это для специалистов. Синтаксис там простой, библиотек море.
Вот ассемблер — это для специалистов.
Александр Мельник
13 мая 2022, 19:29
0
с этим почти согласен. Ну разве что php-fpm не является серверов, это процесс демон интерпретатора php.
Алексей Смирнов
13 мая 2022, 19:23
+1
Ерунда какая-то, это мое мнение! Я быстрее страницу заверстаю!
Ну и не используйте это решение.
Тем более тут вопрос не в быстроте верстки, а управлении повторяющимися блочками.
И кстати это самое управление уже много кто так или иначе реализовали. (Контент блоки, MagicThemes, и прочее)
Теперь, вот, есть решение на MIGX.
Василий Наумкин
13 мая 2022, 18:30
0
Да, это конечно сложнее чем запустить первичную установку WP или MODX
Это просто 2 разных уровня сложности и мастерства.

На MODX и WP можно пилить сайты вообще без знаний, просто кликая мышкой. А Nuxt и прочее Node.js это уже для серьёзных специалистов.

Придётся учиться, но оно того стоит.
Василий Наумкин
13 мая 2022, 18:26
+2
Это все равно если бы мы писали программу на php, переносили ее на продакшен, так запускали локальный веб сервер php
Вообще-то, именно так и происходит.

Сам Nginx умеет отдавать только статичные файлы, а обработку php он передаёт другому процессу. Как правило, это php-fpm, который непрерывно крутится в памяти сервера. И для запуска нового сайта на хостинге этот процесс нужно перезапускать.

Разница лишь в том, что сервер php запускает ваш хостер. А сервер node.js нужно запускать самому. Но это говорит лишь о неразвитости хостинга для node. Я могу себе представить с будущем хостинги для node, где всё будет настроено так же удобно, как сегодня для php.

Ровно так же Nginx может отдавать обработку запроса в ruby, python, go, опять же в node.js и еще много куда. Сам Nginx этого ничего не умеет, потому что он reverse-proxy server.

Для справки, Apache2 работу с php тоже сам по себе не поддерживает, он это делает через встроенный модуль mod_php, который может быть и отключен.
Georg
13 мая 2022, 14:27
0
А никто не сталкивался если нужно сделать тоже самое но с .php? Такой вариант ломает админку:
#301 редирект с example.com/page.html на example.com/page
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.php\ HTTP/
RewriteRule ^(.*)\.php$ /$1 [R=301,L]
Как можно сделать?
Артур Шевченко
13 мая 2022, 14:15
0
Надо уточнить, данный метод даёт возможность контент-менеджеру управлять структурой страниц и нужен он в первую очередь для этого.
Александр Мельник
13 мая 2022, 14:08
0
гугл умеет хорошо индексировать без ssr, а вот яндекс, вы правы, не хочет.
Futuris
13 мая 2022, 13:48
0
Попробую переключиться на nginx и настроить как вы советуете. Спасибо!
vectorserver
13 мая 2022, 13:25
-1
Ерунда какая-то, это мое мнение! Я быстрее страницу заверстаю!
Артур Шевченко
13 мая 2022, 13:14
0
Другой вариант просто к ссылке на каталог добавить get-параметр с нужной опцией и значением.