Сохранение результатов работы пользователя при завершении сессии

MikhailK

Новичок
Сохранение результатов работы пользователя при завершении сессии

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

В идеале (чтобы вообще нигде ничего не менять в самой CMS) было бы ловить пришедший массив $_POST, записывать его в сесиию, проводить авторизацию (при этом исходный массив $_POST затрется), и если авторизация прошла успешно, то редиректиться черех хеадер как-то впихивая в поток сохраненный выше в сессионных переменных массив $_POST. Но, как я понял, так нельзя. Вернее, отправить массив методом POST можно, но одновременно с этим туда перейти нельзя.

Основной метод, как я понял, почитав по этой тематике - передавать массив $_POST через сессию. Однако, в моем случае придется переписывать много кода. Поэтому от этого варианта я отказался.

Можно повесить на сабмит каждой формы проверку через AJAX, не кончилась ли сессия и, если кончилась, добавлять к полям формы поля login/password. Это тоже трудозатратный вариант, хотя и менее.

Еще вариант, который мне кажется разумным - формировать на основе пришедшего массива $_POST hidden-поля в форме повторной авторизации, чтобы этот массив $_POST пришел еще раз, но уже с логином и паролем. Этот вариант самый низкозатратный, если не считать, что внутри массива $_POST могут быть как обычные значения, так и массивы. Хорошо, хоть, не деревья.

Вопрос в том - нет ли какого более простого способа.


Или может быть не заморачиваться, а повесить на интерфейс javascript'ик, который будет через AJAX дергать сервер раз в минуту, имитируя активность пользователя?
 

dimagolov

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

DiMA

php.spb.ru
Команда форума
через аякс - самое простое, но будет постоянно глючить (зависнет один запрос и обновлялка потихому загнется)

я делаю так, это намного проще и быстрее: http://phpclub.ru/talk/showthread.php?s=&threadid=115181
 

MikhailK

Новичок
Автор оригинала: DiMA
я делаю так, это намного проще и быстрее: http://phpclub.ru/talk/showthread.php?s=&threadid=115181
у меня сессии хранятся вечно и каждые 10 минут запускается мой скрипт, сканирующий накопившиеся файлы - это?

у меня система ставится на разные хостинги, доступа на такой уровень, если я правильно понимаю механизм, у меня как правило нет.


Автор оригинала: dimagolov
можно сохранять в сессии ссылку на форму, при отправке которой была запрошена авторизация и повторно отобразить ее заполнив данными из запомненного в сессии $_POST, а уж пользователь ее отправит второй раз.
Этот вариант по трудозатратам сопоставим с внесением изменений в скрипты модулей.

-~{}~ 20.07.09 16:28:

Только что сделал пересылку через поля с типом hidden для простых значений массива $_POST - все получилось элементарно и, что главное, сразу заработало. ))

Теперь бы разобраться как разложить в хидден-поля примерно такой массив, пришедший через POST:
Код:
 [tst] => Array
        (
            [0] => Array
                (
                    [title] => 11111
                    [date] => 
                    [author] => 
                    [text] => 
                    [num] => 0
                )

            [1] => Array
                (
                    [title] => 222222
                    [date] => 
                    [author] => 
                    [text] => 
                    [num] => 1
                )

        )
 

DiMA

php.spb.ru
Команда форума
> если я правильно понимаю механизм, у меня как правило нет.

не правильно понимаешь
есть

мой вариант - единственный, который не потребует какой-либо доработки/программирования и т.д. (кроме скрипта выборочной чистки сессий)
 

MikhailK

Новичок
Автор оригинала: DiMA
> если я правильно понимаю механизм, у меня как правило нет.

не правильно понимаешь
есть

мой вариант - единственный, который не потребует какой-либо доработки/программирования и т.д. (кроме скрипта выборочной чистки сессий)
Если на хостинге время сессий в параметрах 14400, то как я могу сделать сессию бесконечной?


В общем, в моем варианте, через поля hidden все получилось.
Пришлось добавить 25 строк кода в скрипт и 3 строки в темплейт.
В скрипте можно было обойтись меньшим объемом, если написать рекурсивную функцию, но мне трех уровней хватает, поэтому заморачиваться не стал.
 

DiMA

php.spb.ru
Команда форума
> как я могу сделать сессию бесконечной?

прочитав документацию и узнав про 3-4 способа изменения опций пхп (+ узнать об исключительных опциях, которые реально без админских прав не сменить)
 

Alexandre

PHPПенсионер
, то как я могу сделать сессию бесконечной?
если сделаешь ее бесконечной - то со временем закончится место на диске только из-за одних сессий
подумай - сколько всяких ботов ползает ежедневно по твоему сайту
сессии надо чистить
 

DiMA

php.spb.ru
Команда форума
Alexandre
смысл метода - бесконечно (месяц) хранить сессии только админов или круга важных юзеров
 

dimagolov

Новичок
DiMA, вот нафига советовать этот свой костыль всем подряд? ну работает у тебя, и радуйся жизни, но зачем доказывать, что это самое правильное решение всех возможных проблем с сессией?
 

DiMA

php.spb.ru
Команда форума
я же ответил - не имею желания писать ни единой строки кода для решения описанной задачи.. ну ладно, тока строк 15 чистильщика
 

fixxxer

К.О.
Партнер клуба
тут для начала нужен ответ на вопрос, что нужно сохранить - (1)все данные из сессии, (2)или только авторизацию.

если п.1 - то это вовсе не костыль ибо сама постановка задачи такова - "долгоживущая сессия":)

как решается п.2 смотреть в исходниках, например, этого самого форума, куда я щас пишу
 

MikhailK

Новичок
Автор оригинала: fixxxer
тут для начала нужен ответ на вопрос, что нужно сохранить - (1)все данные из сессии, (2)или только авторизацию.

если п.1 - то это вовсе не костыль ибо сама постановка задачи такова - "долгоживущая сессия":)

как решается п.2 смотреть в исходниках, например, этого самого форума, куда я щас пишу
Если про мой исходный вопрос, то мне хранить сессию вечно как раз не нужно. Как и данные авторизации.
Все то нужно - это сохранить пришедшие в массиве $_POST данные и затем, если пользователь подтвердил авторизацию, применить их по назначению.
Если бы я писал приложение с нуля, я бы элементарно передавал бы эти данные через сессионные переменные и даже этим вопросом бы не озадачился.

-~{}~ 20.07.09 23:33:

Автор оригинала: DiMA
> как я могу сделать сессию бесконечной?

прочитав документацию и узнав про 3-4 способа изменения опций пхп (+ узнать об исключительных опциях, которые реально без админских прав не сменить)
Ну, поставив на РАЗНЫЕ хостинги несколько десятков сайтов, Вы бы удивились параноидально-изощренному подходу некоторых хостеров. Иногда заблокировано все, включая ini_set, на который Вы тут прозрачно намекаете. Про собственные настройки php.ini я вообще молчу.

Сорри за оффтоп, но однажды я столкнулся с тем, что была заблокирована функция phpinfo();
На вопрос, как я могу посмотреть конфигурацию PHP, мне бвло вежливо замечено, что мне это не нужно. А если у меня есть "конкретные" вопросы, то я могу их задать и они мне ответят - "да" или "нет". :)
 

Активист

Активист
Команда форума
MikhailK
Ты уже на ряд вопросов ответил сам.

1. По всякому у тебя один или совсем немного админских главных шаблонов - вставляй туда раз в 10 минут запрос на ajax, данные сессий будут обновляться и она не удалится с сервера, избыточность трафика - минимальная и юзер вечно "живой" пока в визуальном редакторе набирает контент
(кстати, хорошая идея. Как-то клиент меня просил "я пишу пишу... а потом вдруг "авторизация".. Я три часа писала!!!. Надо было так и сделать )

2. Реализовать систему "авто входа" по кукам. По всякому у тебя есть одна точка входа, так вот, если юзер не авторизирован, то авторизируй по куке (в куке хранить юзер ид и хеш пароля). Если нет единой точки входа (frontend'а), то делай по пункту 1 и не .. мозг. Да, в этом случае, есть вероятность угона пароля по XSS. А XSS на каждом сайте. Но это уже вина самого чела, если тыкать ссылки будет разные. (про это тебе говорил fixxxer)

3.
> Все то нужно - это сохранить пришедшие в массиве $_POST данные и
> затем, если пользователь подтвердил авторизацию, применить их по
> назначению.
Это самый трудоемкий процесс. Во-первых, работать будет криво, во-вторных - менять больше чем в 1 и 2. Это можно реализовать, если у тебя опять же одна точка входа. Получая данные на точку входа проверяй, есть ли авторизация, если нет, сохраняешь данные $_POST (например в сессию), после авторизации, запускаешь некое действие, которое записывает из сессии в $_POST данные и запускаешь экшен до авторизации. Но здесь есть еще один огромный минус (в отличии от 1 и 2) - POST та ты сохранишь, а вот как быть с $_FILES? Не известно в какой момент у тебя удалится загруженный файл из временной директории.
 

MikhailK

Новичок
я уже реализовал п.3
это оказалось минимальной доработкой, именно потому что у меня одна точка входа.

почему криво, не совсем понятно.

Относительно запускаешь некое действие, которое записывает из сессии в $_POST данные - вот это как раз может работать криво. Либо надо высылать данные методом POST соответствующей функцией (этот вариант я проверил первым), а потом редиректиться туда через хеадер, либо формировать какую-то проходную форму с данными, которую программно сабмитить. Ну так я сделал проще - я просто забабахал весь массив $_POST в форму авторизации в виде hidden-полей. Он вместе с логином/паролем и придет в систему.

Про $_FILES я, естественно, помню, но его сохранять потребности не было (иначе я бы указал в вопросе).


ЗЫ. И еще раз повторюсь, задача стояла не в том, чтобы поймать массив пост и затем его обработать, а в том, чтобы метод промежуточной авторизации был прозрачным для самой системы. Т.е., чтобы система не почувствовала разницы.
 

Активист

Активист
Команда форума
MikhailK
> $_POST в форму авторизации в виде hidden-полей

> а потом редиректиться туда через хеадер,
> либо формировать какую-то проходную форму с данными,
> которую программно сабмитить.
Жесть... Пример ниже (о том, как записать в POST данные)

PHP:
// Ой!? Юзер авторизировался но до этого что-то делал?!
// Видать срок сессии закончился... надо бы 
// записать данные в суперглобольный массив $_POST 
$_POST = $_SESSION['old_post_data'];

// Уффф... записали, надо бы сохраниться
$some_controller->action($_SESSION['old_action']);

// Сохранились.. Я молодец!!! Удалю-ка я лишнее
unset($_SESSION['old_post_data']);
-~{}~ 21.07.09 05:11:

А криво - потому что криво.
1. Зачем юзеру делать "неприятно" и заставлять вводить данные.
2. $_FILES;
 

Rin

*
Активист
да, $_FILES похерятся, но это не страшные потери на фоне остального, +1
 

dimagolov

Новичок
Что мешает сохранить $_FILES аналогично? перенести во временную директорию (ее чистить надо будет) и подправить tmp_name на новое место?
 

Активист

Активист
Команда форума
dimagolov
Что мешает в шаблон TPL'я вставить? И не усложнять систему?
PHP:
<script>
function prolong() {
$.ajax({url: "/some.code.wich.start.session.php", сache: false, success: function(data){}, error: function(e){console.log('Error:"+ e.responceText)}});
setTimeout(prolong(), 1000*60*10);
}

$(document).ready({
prolong();
})
</script>

<?php
//
// some.code.wich.start.session.php
// 
session_start();
echo "OK";
?>
-~{}~ 21.07.09 08:46:

Какое из трех решение, скажем. красивее? Естественно, правильнее делать авторизацию через куку, либо использовать JS (выше), на крайний случай, можно и воткнуть костыль в виде "повторной пересылки POST'а", на крайней случай - увеличить срок жизни сессии, ну а если, например, совсем извратиться - то ввести собственный механизм хранения сессий.
 

Mandor

Новичок
Если CMS построена на авторизации по куке с паролем, то однозначно надо просто переавторизовываться при посылке, вернее это происходило бы автоматически.

Если есть только кука с id сессии, то я бы пинговал сервер из js, со страницы редактирования - проблему решает. Hidden поле с паролем - плохо. Остальные варианты тоже не идеальны.

Я бы мог предложить несколько вариантов, но зачем? Нужно простое и надежное решение - это пинговалка.
 
Сверху