Как повторно инициализировать сеанс в PHP? - PullRequest
3 голосов
/ 28 ноября 2008

Я пытаюсь интегрировать существующую платёжную платформу в мой интернет-магазин. После успешной транзакции платежная платформа отправляет запрос на URL в моем приложении с идентификатором транзакции, включенным в параметры запроса.

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

$sessionId = 'foo'; // the sessionId is succesfully retrieved from the XML response
session_id($sessionId);
session_start();

Приведенный выше код работает нормально, но $_SESSION все еще пуст. Я что-то пропускаю или это просто невозможно?

EDIT:

Спасибо за все ответы. Проблема еще не решена. Как уже было сказано, странно то, что я могу успешно начать новый сеанс, используя идентификатор_ сеанса, принадлежащий пользователю, который разместил заказ. Есть другие идеи?

Ответы [ 7 ]

4 голосов
/ 28 ноября 2008

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

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

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

Третья проблема - если у вас есть решение для балансировки нагрузки с индивидуальным управлением сеансами (очень распространенное), то у вас не будет гарантии, что сервер платежей и ваш клиент достигнут одного и того же веб-сервера (поскольку обычно используется источник липкости основанный на IP).

3 голосов
/ 29 ноября 2008

Рискну предположить, что, поскольку домены отличаются от того, где установлен сеанс, и где вы пытаетесь его прочитать, php проигрывает их безопасно и не получает данные сеанса, установленные другим доменом. Это делается для того, чтобы сохранить безопасность на случай, если кто-то угадает идентификатор сеанса и перехватывает данные.

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

По сути, все, что делает, - это дублирует функциональность, которую вы пытаетесь получить из сеансов, без раздражающих побочных эффектов безопасности.

1 голос
/ 30 ноября 2008

Большое спасибо за все ответы.

Ответ Смазурова заставил меня задуматься и снова заставил меня пропустить мою конфигурацию PHP.

По умолчанию PHP не шифрует данные, относящиеся к сеансу, что должно сделать возможным считывание данных сеанса после перезапуска старого сеанса с другого клиента. Однако я использую Suhosin для исправления и предотвращения некоторых проблем безопасности. Поведение Suhosin по умолчанию заключается в шифровании данных сеанса на основе User Agent , что затрудняет считывание сеансов других людей.

Это было также причиной моих проблем; отключение этого поведения решило проблему.

0 голосов
/ 29 ноября 2008

Убедитесь, что вы закрываете текущий сеанс, прежде чем пытаться начать новый. Так что вы должны делать:

$id = 'abc123';
session_write_close();
session_id($id);
session_start();
0 голосов
/ 29 ноября 2008

Я не уверен, точный промежуток времени между вашей транзакцией и вашим чеком; но, конечно, кажется, что ваш сеансовый файл cookie истек. Сеансы истекают обычно через 45 минут или около того по умолчанию. Это делается для того, чтобы освободить больше uniqid для использования php и предотвратить возможный угон сеанса.

Я не уверен, есть ли у вас пользовательский обработчик сеансов и хранится ли он в базе данных, но исходя из ваших сообщений и комментариев на этой странице, я бы предположил, что он хранится в файлах cookie на стороне сервера.

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

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

Вы увидите эти файлы cookie в папке вашего сервера / tmp, попробуйте найти файл cookie, он должен называться 'sess' + $ session_id.

0 голосов
/ 28 ноября 2008

Как насчет того, чтобы сделать это на другой странице PHP, и вы добавите / перенаправите пользователя iframe на вторую страницу?

0 голосов
/ 28 ноября 2008

Грязно, но у меня сработало:

Скажите платежному шлюзу использовать

http://yourdomain.com/callbackurl.php?PHPSESSID=SESSIONIDHERE

PHP использует этот метод передачи сеанса вокруг себя, если вы устанавливаете определенные конфигурационные переменные (session.use_trans_sid), и, похоже, он работает, даже если PHP было сказано не делать этого. Это, конечно, всегда работало для меня.

Edit:

Ваша проблема может заключаться в том, что для session.auto_start задано значение true - поэтому сессия запускается автоматически с использованием любого идентификатора, который он генерирует, до запуска кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...