Сессия регенерации вызывает истекший сеанс с быстрым вызовом 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-запрос, чтобы получить новый сеанс, и только при успешном выполнении всех остальных запросов
Надеюсь, что кое-что из того, что я написал, поможет вам найти решение.
Удачи.