Взорвался мозг. Нужен механизм одного окна

Активист

Активист
Команда форума
Короче, пользователи натупили мама не горюй! Есть сервис по бронированию мест, основан на сессиях, пошаговый. Сейчас юзер затупил, купил места которых нет.

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

Или остается только проверять постоянно формы его страницы и данные с сессией?
 
Последнее редактирование:

AnrDaemon

Продвинутый новичок
Что-то вроде.
И дополнительный шаг подтверждения заказа. Хотя он у тебя наверное и так есть.
 

Активист

Активист
Команда форума
Что-то вроде.
И дополнительный шаг подтверждения заказа. Хотя он у тебя наверное и так есть.
Воткнул "токен", через md5 хеш ключевых параметров сессии на все ajax методы и формы, до сохранения заказа по старым формам и страницам не дойдут, увидят злостное сообщение по поводу нескольких вкладок. Подтверждение есть, на странице оплаты брони, но кто бы там проверял данные и вообще читал.
 

WMix

герр M:)ller
Партнер клуба
а зачем же ты так все завязал на сессии? простой voyage_id по GET лень передавать было?
 

Активист

Активист
Команда форума
а зачем же ты так все завязал на сессии? простой voyage_id по GET лень передавать было?
В сессии хранится очень большой объект "сессия поиска", включает много всего, бронирование очень растянуто на шаги.
 

WMix

герр M:)ller
Партнер клуба
ну и храни (лучше конечно сразу в базе), но храни массив записей, а при оплате или в шагах передавай индекс массива GETом, чтоб выбрать правильную запись
 

Adelf

Administrator
Команда форума
А нельзя при бронировании в другой вкладке - отдавать текущий шаг?
т.е. в сессии все бронирование и оно единственно. И если он в другой вкладке хочет еще бронировать - пусть отдается текущий шаг в первой вкладки.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ты сначала определись: надо сделать хорошо или быстро?
если быстро - добавляй проверки и костыли, пофиг какие,
если хорошо - отделяй мухи от котлет, поиск и заказ - разные действия, и не должны быть связаны,
для заказа делается корзина в постоянном хранилище, для поиска вариант - кука с флагами значений,
в описанном приложении ошибка в генах, нужен серьезный рефакторинг и переработка архитектуры
 

AnrDaemon

Продвинутый новичок
ну и храни (лучше конечно сразу в базе), но храни массив записей, а при оплате или в шагах передавай индекс массива GETом, чтоб выбрать правильную запись
Кто запретит мну открыть копию страницы в соседней вкладке? Две-три копии…
Такие вещи должны храниться независимо от URL.
 

fixxxer

К.О.
Партнер клуба
Кто запретит мну открыть копию страницы в соседней вкладке?
Это меньшая из проблем, if (session[request.operationIndex].step != request.step) redirect_to_step(session[request.operationIndex].step)
 

Активист

Активист
Команда форума
ты сначала определись: надо сделать хорошо или быстро?
если быстро - добавляй проверки и костыли, пофиг какие,
если хорошо - отделяй мухи от котлет, поиск и заказ - разные действия, и не должны быть связаны,
для заказа делается корзина в постоянном хранилище, для поиска вариант - кука с флагами значений,
в описанном приложении ошибка в генах, нужен серьезный рефакторинг и переработка архитектуры
Да ну?)) Если бы все было так просто

У меня шаги:
1. Выбор направления (региона)
2. Выбор ст. отправления , выбор ст. прибытия, дата.
3. Выбор рейса.
4. Далее, если по групповому идентификатору ФИАС уровня населенного пункта есть несколько точек отправления (например разные оп в пределах города), то юзер может уточнить, где он сядет.
5. Выбор мест , указание мобильного, бронирование. Поскольку сама структура данных очень сложная (вычисление временных оффсетов от ст. отправления, промежуточные станциии отправления, по отрезкам маршрута определние стоимости, промежуточные станции прибытия), закрытые места - идут сложные процессы определения свободно ли места. Уточнее типа билета, уточнее количества ручной клади.

а. Вся бронь идет без регистрации, на сессию нельзя забронировать более 4-х билетов;
б. На бронь после выбора первого места выдается не более 5-ти минут на сессию;
г. По сессии идет анализатор бота , если он замечает нетипичное повидение пользователя сбрасывает все.
д. Очень, ОЧЕНЬ много аякса с адаптивной версткой под разные типы устройств и разными блоками и содержымым (40% мобильников, 20% планшетов), поэтому вешать все на сферичиеский УРЛы просто глупо, поскольку на любой из этапов по ТЗ могут вноситься координальные изменения, а коррекция заказа на страницах (те же типы места). Вводить вторую "сессию" (идентификатор в УРЛ) приведет к злоупотреблению со стороны конкурентных перевозчиков (и так вырубают , да и что мешает пользователю скопировать УРЛ, вместе с идентификатором собственной сессии? Где там мухи, где котлеты?
 

Активист

Активист
Команда форума
А нельзя при бронировании в другой вкладке - отдавать текущий шаг?
т.е. в сессии все бронирование и оно единственно. И если он в другой вкладке хочет еще бронировать - пусть отдается текущий шаг в первой вкладки.
Так и есть. Но это как выяснилось, не решает проблему (см. ниже)

Это меньшая из проблем, if (session[request.operationIndex].step != request.step) redirect_to_step(session[request.operationIndex].step)
Ясен есть такая проверка, но она не помогла. Суть сошла на следующее.

1. Юзер дошел до пятого шага, на его экране автобус, с выбором места и выбором типа мест и одна строчка "укажите мобильный". У юзера страница не рефрешется (вкладка 1).
2. Юзер открыл другую вкладку, натыкал новый поиск на другой день, он дошел до 5-го шага, ему не понравилось сидеть спиной к водителю (тип автобуса другой, узнали позвонив ему), закрыл вкладку (вкладка 2).
3. Юзер видит старую вкладку (вкладка 1, шаг 5), прошла всего две минуты, страница по таймауту бронирования не закрыта. В сессии данные по другому рейсу (вкладка 2, шаг 5), но по тому же направлению, юзер тыкает на места (а они свободны на обоих рейсах), бронирует (естественно на рейс вкладки 2), видя вкладку 1. При этом по аяксу ему приходит эскиз билета с данными на рейс вкладки 2, но он сцуко упорытый и этого тоже не видит.
4. Находясь под веществами На странице оплаты заказа он забивает болт и не проверяет заказ (ни дату ни рейс), ему приходит электронный билет, он охеревает, что купил хз что, ведь тыкал он в места совсем другого рейса. Звонить и кроет матом.

При этом у меня на каждом этапе с 1 по 5-тый проверяется всё, если юзер на 3 шаге, ожидаемые данные на 4,5 - очищаются, проверяет целостность данных от первого до текущего шага. Очистка временных билетов из БД, в общем, целостность данных гарантирована.

PS. Это реальный пользователь, его поведение вытащино из внутренного детального лога поведения пользователя по сессии и восстановлено посекундно.
 

Активист

Активист
Команда форума
Вообще токен оказался очень универсальным средством,и очень полезным на всех этапах.

Код:
public function getToken()
    {
       $schedule_id = $this->getSelectedSchedule() ? $this->getSelectedSchedule()->getId() : null;
       $dispatch_station = $this->getDispatchStation() ? $this->getDispatchStation() : null;
       $arrival_station = $this->getArrivalStation() ? $this->getArrivalStation() : null;
       $dispatch_datetime = $this->getDispatchDatetime();
       $time_up = $this->getTimeUp()->getTimestamp();
       $timezone = $this->getTimezone();
    
       return md5(sprintf("%s|%s|%s|%s|%s|%s", $schedule_id, $dispatch_station, $arrival_station, $dispatch_datetime, $time_up,  $timezone));
    }
Т.е. когда приходят данные md5, я сравниваю ее с md5 текущей сессии, и если форма от другой окна/шага/пришла из космоса, шлю лесом. При этом свободен с реализацией интерфейса пользователя, а ввод новых параметров сводится к коррекции одного метода.
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Да ну?)) Если бы все было так просто

У меня шаги:
1. Выбор направления (региона)
2. Выбор ст. отправления , выбор ст. прибытия, дата.
3. Выбор рейса.
4. Далее, если по групповому идентификатору ФИАС уровня населенного пункта есть несколько точек отправления (например разные оп в пределах города), то юзер может уточнить, где он сядет.
Все эти параметры можно хранить в local storage браузера?
я не знаю какие у тебя UA, если нужна совместимость с IE6 - храни в редисе
5. Выбор мест , указание мобильного, бронирование. Поскольку сама структура данных очень сложная (вычисление временных оффсетов от ст. отправления, промежуточные станциии отправления, по отрезкам маршрута определние стоимости, промежуточные станции прибытия), закрытые места - идут сложные процессы определения свободно ли места. Уточнее типа билета, уточнее количества ручной клади.
Оформление - это отдельный процесс. Выбранные места, как товары, надо писать в базу как детали заказа, лучше по ajax, с мобильным клиента и прочими параметрами.
У тебя нет ничего необычного, оформление с проверкой наличия, расчет стоимости доставки - это сложная многошаговая операция в любом крупном ecommerce.
В магазинах операторы еще мониторят незавершенные заказы и перезванивают клиентам, помогают заплатить.

а. Вся бронь идет без регистрации, на сессию нельзя забронировать более 4-х билетов;
г. По сессии идет анализатор бота
аналогично всем серьезным магазинам
б. На бронь после выбора первого места выдается не более 5-ти минут на сессию;
это мелочь
д. Очень, ОЧЕНЬ много аякса с адаптивной версткой под разные типы устройств и разными блоками и содержымым (40% мобильников, 20% планшетов), поэтому вешать все на сферичиеский УРЛы просто глупо
я не предлагал сериализацию в GET-параметры, я предлагал разделить выбор услуги и ее оформление
на любой из этапов по ТЗ могут вноситься координальные изменения
CRUD деталей заказа? для меня в этом нет ничего нового
Вводить вторую "сессию" (идентификатор в УРЛ) приведет к злоупотреблению со стороны конкурентных перевозчиков (и так вырубают , да и что мешает пользователю скопировать УРЛ, вместе с идентификатором собственной сессии? Где там мухи, где котлеты?
у тебя, очевидно, я все это уже делал, и ни одного разрыва идентификатора URL

Вообще токен оказался очень универсальным средством,и очень полезным на всех этапах.
https://en.wikipedia.org/wiki/Cross-site_request_forgery#Synchronizer_token_pattern
да, этот механизм несколько лет назад стали включать в фреймворки как стандартный, он вообще рекомендуется всегда,
а еще у тебя есть проблема в архитектуре
 
Последнее редактирование:

Активист

Активист
Команда форума
Все эти параметры можно хранить в local storage браузера?
я не знаю какие у тебя UA, если нужна совместимость с IE6 - храни в редисе

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

аналогично всем серьезным магазинам

это мелочь

я не предлагал сериализацию в GET-параметры, я предлагал разделить выбор услуги и ее оформление

CRUD деталей заказа? для меня в этом нет ничего нового

у тебя, очевидно, я все это уже делал, и ни одного разрыва идентификатора URL


https://en.wikipedia.org/wiki/Cross-site_request_forgery#Synchronizer_token_pattern
да, этот механизм несколько лет назад стали включать в фреймворки как стандартный, он вообще рекомендуется всегда,
а еще у тебя есть проблема в архитектуре
Б**, братан, извини что уж так обращаюсь, но я говорил о другом - о тупости пользователей, просто о ТУПОСТИ , что юзер даже видя что на этапе оплаты он не обратил внимание на содержание заказа, а на этапе бронирования бронировал совсем другое, это может быть основанием. Все продумано, какие основание рефакторинга я хз Так, что бы понимать меру отвественности глянь видео. Рефакторинг не нужен, имхо, все там и так прозрачно и отлажено. После когда выложу в паблик бету покажу сам сайт.
А так вот видос. ЗЫ нихера не е-коммерц, а больше и отвественнее))
 
Последнее редактирование:

MiksIr

miksir@home:~$
о тупости пользователей, просто о ТУПОСТИ , что юзер даже видя что на этапе оплаты он не обратил внимание на содержание заказа, а на этапе бронирования бронировал совсем другое, это может быть основанием
Тупость пользователя, многие из которых плохо дружат с компьютерами вообще, хорошо известна, прогнозируема и решаема на уровне интерфейса. Конечно, когда интерфейсами занимаются профессионалы, а не программисты.
А вот тупость описанной ситуации на уровне реализации... ей оправдания нет. Мне казалось, это ошибка начинающих. Даже если сохранение шагов в единой сессии оправдано (а это случается очень редко, и явно не тот случай) - гоняют через клиента токен состояния, по которому сервер прервет цепочку, если между шагами кто-то влез в сессию.
 

fixxxer

К.О.
Партнер клуба
Не бывает тупых пользователей, бывает непроработанный кейс.
Пользователь всегда сделает что угодно и как угодно, его право. С такими претензиями - в госорганы в суппорт, и махать руками что не читают инструкцию.
 

MiksIr

miksir@home:~$
Тупой в данном случае как антоним "продвинутуму". Который знает какой веб на самом деле и ничему не доверяет и может разобраться - как же все на самом деле работает, если ему это нужно ;) Не удачный антоним, но взял что было выше ;)
 
Сверху