Сессия регенерации вызывает истекший сеанс с быстрым вызовом AJAX

Мое приложение представляет собой полную веб-страницу AJAX, используя Codeigniter Framework и обработчик сеанса memcached.

Иногда он отправляет много асинхронных вызовов, и если сеанс должен восстановить свой идентификатор (чтобы избежать проблемы безопасности при фиксации сеанса), cookie сеанса не обновляется достаточно быстро, а некоторые вызовы AJAX терпят неудачу из-за истекшего идентификатора сеанса.

Вот схематическая картина, которую я сделал, чтобы четко показать проблему: введите описание изображения здесь

Я прошел через подобные потоки (например этот), но ответы на самом деле не решают мою проблему, я не могу отключить безопасность, поскольку в моем приложении есть только вызовы AJAX.

Тем не менее, у меня есть идея, и я хотел бы получить мнение до того, как взломать классы обработчиков сеансов Codeigniter: Идея состоит в том, чтобы управлять двумя одновременными идентификаторами сеанса на некоторое время, например 30 секунд. Это будет максимальное время выполнения запроса. Поэтому после восстановления сеанса сервер все равно примет предыдущий идентификатор сеанса и переключится на сеанс на новый. Используя ту же картинку, которая даст что-то вроде этого:

введите описание изображения здесь

Ответ 1

Прежде всего, ваше предлагаемое решение вполне разумно. Фактически люди в OSWAP сообщают только, что:

Веб-приложение может реализовать дополнительный тайм-аут продления, после которого идентификатор сеанса автоматически обновляется. (...) Предыдущее значение идентификатора сеанса все равно будет действительным в течение некоторого времени, с учетом интервала безопасности, прежде чем клиент узнает о новом ID и начинает его использовать. В то время, когда клиент переключается на новый идентификатор внутри текущего сеанса, приложение аннулирует предыдущий идентификатор.

К сожалению, это невозможно реализовать с помощью стандартного управления сеансом PHP (или я не знаю, как это сделать). Тем не менее, реализация этого поведения в пользовательский драйвер сеанса 1 не должна представлять серьезной проблемы.

Теперь я сделаю смелое выражение: вся идея обновления идентификатора сеанса периодически прерывается. Теперь не поймите меня неправильно, регенерируя идентификатор сеанса при входе в систему (или, точнее, в качестве OSWAP поместил его, на "изменение уровня привилегий" ) действительно является очень хорошей защитой от фиксации сеанса.

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

Существует лучшая (и более простая) защита от простой кражи сеанса: используйте SSL (HTTPS). Обновление периодической сессии следует рассматривать как обходной путь бедного человека к этому вектору атаки.


1ссылка на стандартный способ PHP

Ответ 2

Ваша проблема, по-видимому, меньше связана с фактической скоростью запросов (хотя это и является фактором), но больше с concurrency. Если я правильно понимаю, ваше приложение javascript делает много асинхронных вызовов async - быстро (предположительно в пакетах), а иногда некоторые из них терпят неудачу из-за недействительности сессии из-за того, что, по вашему мнению, является скоростью запросов. Ну, я думаю, что проблема в том, что на самом деле у вас на сервере несколько одновременных запросов, в то время как первый из них возобновил свою сессию, другой, по сути, не видит его, потому что запрос уже сделан и ожидает обработки сервером.

Эта проблема, конечно, проявится только при одновременном выполнении нескольких запросов для одного и того же пользователя.

Теперь Настоящий вопрос здесь - что в вашем приложении требует бизнес-логика?

Мне кажется, что вы пытаетесь найти техническое решение проблемы "бизнеса". Я имею в виду, что либо вы неправильно интерпретировали свои требования, либо требования просто не так хорошо продуманы/указаны.

Я бы посоветовал вам попробовать следующее:

  • спросите себя, могут ли эти несколько одновременных запросов быть объединены с одним

  • внимательно изучите требования и попытайтесь найти настоящую причину, по которой вы делаете то, что вы делаете, может быть, нет реальной причины для этого.

  • каждый раз, прежде чем вы запускаете серию запросов, запустите "обновить" ajax-запрос, чтобы получить новый сеанс, и только при успешном выполнении всех остальных запросов

Надеюсь, что кое-что из того, что я написал, поможет вам найти решение. Удачи.