Новости Joomla

Quantum Manager нужен сообществу, а автору нужна ваша поддержка!

Quantum Manager нужен сообществу, а автору нужна ваша поддержка!Файловый менеджер Quantum — одно...

Файловый менеджер Quantum — одно из самых популярных решений для Joomla, созданное разработчиком из сообщества Joomla, Дмитрием Цымбалом (@tsymbalmitia). Он делает Quantum удобным, безопасным и современным, обновляет его, исправляет уязвимости и отвечает пользователям — всё это в свободное от основной работы время.

Теперь настал момент для следующего шага: развитие проекта требует больше времени и ресурсов.

0 Пользователей и 1 Гость просматривают эту тему.
  • 15 Ответов
  • 3795 Просмотров
*

RinatM

  • Новичок
  • 9
  • 0 / 0
Доброго времени суток,
Пишу компонент для Joomla 2.5 (MVC): пользователю показывается список вопросов из БД, при выборе вопроса открывается форма для дачи ответа, после ответа пользователь возвращается обратно на страницу со списком вопросов; если в этот момент обновить стр-цу, то ответ пользователя снова уйдет на сервер и запишется в БД (идет повторная отправка данных формы).

Погуглил, выделил 2 общих способа:
1) переменные SESSION (слишком муторно получается, особенно учитывая, что переменные SESSION нужно сначала выставлять, потом обнулять),
2) header('Location: '.$path); ($path - включает несколько переменных _POST, которые динамически формируются, ну и вообще не совсем понятно куда именно ставить эту строчку с учетом использования MVC шаблона).

(пробовал вставить unset($_POST); и JRequest::clean(); на страницу, отображающую список вопросов, не помогло))

Оба этих способа кажутся сложноватыми. Есть ли в Joomla какие-нибудь механизмы обхода этой проблемы? Ну или как вообще посоветуете ее решить?


  
« Последнее редактирование: 30.07.2013, 17:31:48 от RinatM »
*

RinatM

  • Новичок
  • 9
  • 0 / 0
ну чтож конкретно в моем случае пока решил так, добавил следующий код в конец страницы отображающей список вопросов:
...
<?php
   if($_SERVER["REQUEST_METHOD"] == "POST"){      
               $id1= ...;
               $id2=...;      
               $path="index.php?option=com_xxx&task=yyy&view=zzz&id1=".$id."&id2=".$id2;      
      header("Location: ".$path);      
   } ?>

Буду рад если кто-то посоветует более правильное решение.
*

Fedor Vlasenko

  • Живу я здесь
  • 3845
  • 733 / 7
  • https://fedor-vlasenko.web.app
при обработке входящих данных делать запрос в базу проверять есть ли уже ответы пользователя на данную тему, рубрику и т.д
*

RinatM

  • Новичок
  • 9
  • 0 / 0
при обработке входящих данных делать запрос в базу проверять есть ли уже ответы пользователя на данную тему, рубрику и т.д

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

В моем случае при ответе на вопрос идет запись (insert) в таблицу ответов в БД. При этом этот вопрос блокируется и ссылка для ответа на него в списке вопросов - больше неактивна. Но если пользователь напрямую введет в строке браузера: www.mysite.ru/index.php?option=com_xxx&task=yyy&view=zzz&id1=".$id."&id2=".$id2 то у него откроется заблокированный вопрос и он сможет снова ответить, при этом произойдет повторный insert  в таблицу ответов (ключ таблицы - автоинкрементное поле счетчика).

Как быть с такой проблемой? Как от этого защитится?
*

Fedor Vlasenko

  • Живу я здесь
  • 3845
  • 733 / 7
  • https://fedor-vlasenko.web.app
вариант генерировать исключение базой данных при вставке одинакового поля
*

RinatM

  • Новичок
  • 9
  • 0 / 0
вариант генерировать исключение базой данных при вставке одинакового поля

в MySQL есть такое? и можно ли проверять несколько полей (хотя бы 2) на одинаковость?
*

Fedor Vlasenko

  • Живу я здесь
  • 3845
  • 733 / 7
  • https://fedor-vlasenko.web.app
я не знаю как выглядит у вас структура таблицы. Пусть user->id это буде инкремент таблица ваш опрос при вставке повторного значения с тем же  user->id вернет ошибку
if (!$db->execute()) {
echo 'Вы уже ответили';
}
*

RinatM

  • Новичок
  • 9
  • 0 / 0
у меня нету дублирования ключевого поля:

в моем запросе /index.php?option=com_xxx&task=yyy&view=zzz&id1=".$id."&id2=".$id2     ==> id2 - указывает на инкрементное поле, если оно пустое, то соответственно создается новая запись;

когда "недобросовестный" пользователь вбивает: /index.php?option=com_xxx&task=yyy&view=zzz&id1=".$id."&id2=".$id2 - с пустым $id2 - то он снова отвечает на вопрос и записывает новую строку (а не изменяет имеющуюся) в БД (дублирования id2 нету, поэтому проверять его нет смысла).
*

Fedor Vlasenko

  • Живу я здесь
  • 3845
  • 733 / 7
  • https://fedor-vlasenko.web.app
зачем вам id2 тогда передавать не пойму. И вы используете get запросы
в обработчике. Перед выводом списка вопросов можно в этом же запросе и проверять отвечал ли на  его пользователь
*

SDKiller

  • Живу я здесь
  • 2705
  • 329 / 5
  • ...ergo sum
Ну генерируйте свой уникальный token какой-нибудь для юзера - даже лучше id сессии использовать, пишите его в таблицу с ответами и проверяйте при записи - нет ли уже такого.
*

RinatM

  • Новичок
  • 9
  • 0 / 0
Ну генерируйте свой уникальный token какой-нибудь для юзера - даже лучше id сессии использовать, пишите его в таблицу с ответами и проверяйте при записи - нет ли уже такого.

не пойдет, человек сегодня ответил, завтра я ему сказал что ответ неверный он немного подумает, посмотрит в mozille исходный код и послезавтра вобъет в браузере www.mysite.ru/index.php?option=com_xxx&task=yyy&view=zzz&id1=".$id."&id2=".$id2 и даст правильный ответ. и тут id_session - будет уникальный.

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

Fedor Vlasenko

  • Живу я здесь
  • 3845
  • 733 / 7
  • https://fedor-vlasenko.web.app
отправляйте форму методом post. И вам уже дважды говорю не надо отправлять идетинфикатор считывайте его в контроллере.
JFactory::getUser()->id,  JFactory::getSession()->getId()
По безопасной отправке
// вставляем скрытое поле в форму
<?php echo JHtml::_('form.token'); ?>
в контроллере проверяем
JSession::checkToken('post') or jexit(JText::_('JINVALID_TOKEN'));
*

RinatM

  • Новичок
  • 9
  • 0 / 0
отправляйте форму методом post. И вам уже дважды говорю не надо отправлять идетинфикатор считывайте его в контроллере.
JFactory::getUser()->id,  JFactory::getSession()->getId()
По безопасной отправке
// вставляем скрытое поле в форму
<?php echo JHtml::_('form.token'); ?>
в контроллере проверяем
JSession::checkToken('post') or jexit(JText::_('JINVALID_TOKEN'));


Отправляю всегда постом (_POST)
JFactory::getUser()->id,  JFactory::getSession()->getId() - идентификатор пользователя я не отпраывляю (считваю его в модели), отправляю идентификатор учебного заведения, идентификатор задания.

использовать form.token - хорошая идея, остался только вопрос сложно ли его подделать, попробую)...мне не нужна профессиональная защита, нужна просто защита от script kidding.

Спасибо за советы, попробую form.token
*

RinatM

  • Новичок
  • 9
  • 0 / 0
вобщем form.token - не прокатывает, form.token - защита от злоумышленника, который логин и пасс не знает, а мне нужна защита от самого пользователя (недобросовестного), пользователь логинится и после этого вбивает в адресной строке путь напрямую.
*

mohax

  • Давно я тут
  • 901
  • 66 / 3
вобщем form.token - не прокатывает, form.token - защита от злоумышленника, который логин и пасс не знает, а мне нужна защита от самого пользователя (недобросовестного), пользователь логинится и после этого вбивает в адресной строке путь напрямую.
Эм, разве токен выдается не для любого пользователя? Это уникальный идентификатор для формы, показанной конкретному пользователю. И разницы нет, залогинен он или нет. Вообще-то было так раньше)

А по Вашей задаче:

Самое правильное - это сверять по записи в БД. Как вариант, можно сделать еще одно поле (Unique), в него записывать какой-то идентификатор, содержащий в себе id пользователя и id вопроса (хеш например, или просто "id1|id2". Тогда при инсерте в БД будет возвращаться ошибка, если такое сочетание уже было.
*

RinatM

  • Новичок
  • 9
  • 0 / 0
Самое правильное - это сверять по записи в БД. Как вариант, можно сделать еще одно поле (Unique), в него записывать какой-то идентификатор, содержащий в себе id пользователя и id вопроса (хеш например, или просто "id1|id2". Тогда при инсерте в БД будет возвращаться ошибка, если такое сочетание уже было.

Идея интересная, спасибо)..Во 2 версии своего компонента подумаю над такой реализацией.
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

Форма для добавления данных в Google Sheets

Автор zigzagrus

Ответов: 2
Просмотров: 1502
Последний ответ 07.11.2024, 12:03:12
от zigzagrus
Создать словарь с базой данных на Joomla

Автор didarsd

Ответов: 2
Просмотров: 2020
Последний ответ 25.01.2021, 17:23:21
от beliyadm
Скачивание файла после внесения контактных данных Joomla 2.5.11?

Автор marketingMLS

Ответов: 0
Просмотров: 3747
Последний ответ 11.03.2020, 17:25:39
от marketingMLS
Перенос данных с движка на другой движ

Автор exger

Ответов: 0
Просмотров: 1314
Последний ответ 05.12.2018, 01:00:53
от exger
Викторина из одного вопроса: из-за чего могла сломаться функция отправки почты. Ваши варианты?

Автор Adrian1111

Ответов: 0
Просмотров: 1077
Последний ответ 06.07.2017, 09:32:12
от Adrian1111