CCaptchaAction + ajax

Предварительное обсуждение найденных ошибок перед отправкой их авторам фреймворка, а также внесение новых предложений.
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: CCaptchaAction + ajax

Сообщение Ekstazi »

Зачем вы так усложняете ? :)

Код: Выделить всё

    public function rules()
    {
        return array(
// ... 
            array('verifyCode','myCaptcha','captchaAction'=>'site/captcha','message'=>Yii::t('user','Неверный проверочный код'),'allowEmpty'=>!extension_loaded('gd')),
        );
    }

    public function myCaptcha($attr,$params)
    {
        if(Yii::app()->request->isAjaxRequest)
            return;

        CValidator::createValidator('captcha', $this, $attr, $params)->validate($this);
    }
 
SpiLLeR
Сообщения: 350
Зарегистрирован: 2009.09.17, 16:47
Откуда: Санкт-Петербург
Контактная информация:

Re: CCaptchaAction + ajax

Сообщение SpiLLeR »

На мой взгляд, использовать $_POST в модели, так же не верно как и Yii::app()->request->isAjaxRequest.
Все решается просто через установку сценария.
Предупрежден - значит вооружен.
devKP.ru
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: CCaptchaAction + ajax

Сообщение Ekstazi »

Верно, не верно, проблема решилась минимальными усилиями, при этом не усложнив логику.
mrchaos
Сообщения: 18
Зарегистрирован: 2011.03.31, 17:41

Re: CCaptchaAction + ajax

Сообщение mrchaos »

Кстати да, можно сделать проще и логичней, нежели идти по пути MVC и писать код в разных файлах. Порой одна строка кода проще, но не соответствует модели MVC.
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: CCaptchaAction + ajax

Сообщение slavcodev »

mrchaos писал(а):Кстати да, можно сделать проще и логичней, нежели идти по пути MVC и писать код в разных файлах. Порой одна строка кода проще, но не соответствует модели MVC.
Если пишите для себя, то да.
Если пишешь профессиональный код, с расчетом на будущее расширение, на то что твой код может быть, будет поддерживаться другим кодером, тогда лучше придерживаться стандартам.
Жду Yii 3!
mrchaos
Сообщения: 18
Зарегистрирован: 2011.03.31, 17:41

Re: CCaptchaAction + ajax

Сообщение mrchaos »

Ну я пример кода взял с http://www.yiiframework.com/extension/yii-user/
Получается расширения пишут тоже для себя не думая о других.
Для начала оставлю как сделал, далее при реализации остальных вещей исправлю то что будет работать не по форме. На начальном этапе так проще и опыт сын ошибок трудных всё исправит.
Подняв старую тему, нашлось 3 вменяемые реализации :)
Думаю теперь в эту тему не будут писать вопросы что да как.
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: CCaptchaAction + ajax

Сообщение Ekstazi »

Вообще не вижу здесь нарушений концепции MVC, модель обрабатывает/проверяет данные. А контроллер передает их на обработку в модель :) Плодить сценарии, не особо уместно, особенно для модели пользователь, которая не только за регистрацию, но и за настройки и смену пароля и емайла отвечает. И что это получится - порядка 10 сценариев, зато по концепции MVC, "имхо" надо делать код как можно проще и понятней не только для себя, но и для других, а "делать правильно" не всегда лучший способ.
toshkent
Сообщения: 3
Зарегистрирован: 2011.04.08, 09:55

Re: CCaptchaAction + ajax

Сообщение toshkent »

Добавлю свои 5 копеек. Мне вот нужно чтобы капча валидировалась через аякс (по сабмит). Решение достаточно простое.

Код: Выделить всё

<?php $formregister = $this->beginWidget('CActiveForm', array('action'=>Yii::app()->createUrl('main/Register'),  'id'=>'formregister', 'enableAjaxValidation'=>true, 'clientOptions'=>array('validateOnSubmit'=>true,'validateOnChange'=>false),)); ?>
.................
В контроллере в свойствах капчи 'testLimit' => 0, .......... аяксная проверка - стандартная

Код: Выделить всё

    protected function performAjaxValidation($model,$fmModel) {
           if(isset($_POST['ajax']) && $_POST['ajax']==$fmModel) {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
    } 
картинка капчи при неправильном вводе обязательных полей не перегенерируется, а ошибки выводятся (меня кстати постоянная регенерация начинает раздражать, если ошибаюсь при вводе.... и ещё больше регистрация через мыло). тут же слышу в свой адрес... "А как же спам-боты!!!????". Конечно, все хотят взломать имеено ваш суперпродвинутый сайт. Друзья, учим мат часть (и я в том числе). Например, решение aii-anti-spam-behavior http://www.yiiframework.com/extension/a ... m-behavior (или тоже http://www.yiiframework.com/forum/index ... entry64896). И вообще не надо ограничивать себя предлагаемым функционалом, стараемся дружно мыслить "ширше".
Аватара пользователя
BuCeFaL
Сообщения: 447
Зарегистрирован: 2010.03.17, 21:22
Откуда: Kiev
Контактная информация:

Re: CCaptchaAction + ajax

Сообщение BuCeFaL »

Задержка на 2 секунды, в алгоритме спам программы, неприятно вас удивит.
toshkent
Сообщения: 3
Зарегистрирован: 2011.04.08, 09:55

Re: CCaptchaAction + ajax

Сообщение toshkent »

Ну почему же удивит. Капча - не панацея. Я просто привёл пример. Думается, можно было бы создать отдельную тему про то, как бороться со спам-ботами. Эта тема будет всегда актуальна. Ибо, чтобы мы не придумывали, будут найдены способы наши "выдумки" обойти. Это как взлом пароля. Нет такого пароля (шифра, системы), который нельзя было бы взломать-подобрать - вопрос времени. Кста, вот некоторая "пища для ума" по теме спам-боты.
http://pokrovskii.com/izyaschnoe-otseivanie-spama/
http://mycrimea.su/partners/web/access/bot.html
http://mycrimea.su/partners/web/access/
+ можно было бы регистрировать по уникальному e-mail, с подтверждением с этого мыла... (ещё больше задалбывая посетителя :) )
Решение проблемы - комплексное. Я бы с удовольствем сам почитал умные мысли и предложения по этому поводу.
Читаю ....."В мире уже сформировалась своеобразная индустрия по ручному взлому CAPTCHA, использующая дешевый труд в странах с низким уровнем жизни. Однако это требует от спаммеров реальных финансовых затрат, поэтому можно гарантировать, что вашу защиту не станут ломать, пока ваш ресурс не приобретет для спаммеров значительную ценность." .... короче, с нашими сайтами типа "hello world" (прошу прощения, если кого обидел) мы можем спать спокойно.
froggy
Сообщения: 14
Зарегистрирован: 2011.07.30, 13:14

Re: CCaptchaAction + ajax

Сообщение froggy »

Сори что поднимаю старую тему, но столкнулся с такой же проблемой.
В итоге решил использовать сценарии - но ничего не вышло.
Вот мой код:
Контроллер:

Код: Выделить всё


 public function actions() {
        return array(
// captcha action renders the CAPTCHA image displayed on the contact page
            'captcha' => array(
                'class' => 'CCaptchaAction',
                'backColor' => 0xFFFFFF,
                'testLimit' => 1,
            ),

....
....
public function actionPostNew() {
 ....
 if (isset($_POST['Posts'])) {
            $post->attributes = $_POST['Posts'];
            $post->verifyCode = $_POST['Posts']['verifyCode'];
            if (Yii::app()->user->isGuest) {
                $post->setScenario("noAjax");
            }
            if ($post->validate()) {
// form inputs are valid, do something here
                if ($post->save())
                    $this->redirect($_SERVER['HTTP_REFERER']);
            }
        }
        $this->render('application.components.views.postNew', array('post' => $post));
 
Валидация:

Код: Выделить всё

...
array('verifyCode', 'captcha', 'allowEmpty' => !CCaptcha::checkRequirements(), "on" => "noAjax"),
...
 
Так вот - проблема оказалась в том что при

Код: Выделить всё

if ($post->save())  
проходит валидация еще раз, во время которой генерится уже другая капча, а так как капча уже другая то save не сохраняет.

Т.к. код в CActiveRecord

Код: Выделить всё

public function save($runValidation=true,$attributes=null)
    {
        if(!$runValidation || $this->validate($attributes)){
            return $this->getIsNewRecord() ? $this->insert($attributes) : $this->update($attributes);
        }
        else{
            return false;
        }
    } 
В итоге пришел к тому что при решении этой проблемы нужно использовать сценарии и отказаться от второй валидации:

Код: Выделить всё

if ($post->save(false))
                    $this->redirect($_SERVER['HTTP_REFERER']); 
P.S. Версии Yii: 1.1.8
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: CCaptchaAction + ajax

Сообщение esche »

Код: Выделить всё

            if (Yii::app()->user->isGuest) {
                $post->setScenario("noAjax");
            } 
А как связаны гость и ajax? Или так задумано и для всех гостей ajax не работает?
...
froggy
Сообщения: 14
Зарегистрирован: 2011.07.30, 13:14

Re: CCaptchaAction + ajax

Сообщение froggy »

Капча работает только для гостей.
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: CCaptchaAction + ajax

Сообщение esche »

froggy писал(а):Капча работает только для гостей.
А причём тут ajax? =) В обсуждениях выше было приведено решение - отключать капчу (использовать соответствующий сценарий) при ajax-запросе... Добавьте соответствующую проверку и будет работать... Хотя, если текущий вариант устраивает..
...
kukuruku
Сообщения: 1318
Зарегистрирован: 2011.02.14, 11:36

Re: CCaptchaAction + ajax

Сообщение kukuruku »

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

есть идеи?
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: CCaptchaAction + ajax

Сообщение esche »

kukuruku писал(а):...
есть идеи?
Вроде у Вас была идея?
kukuruku писал(а):getVerifyCode тоже знаю, но проблема в том как его вызвать не имея объекта?
или создать объект $c=new CCaptchaAction; $c->getVerifyCode(true) но как то некрасиво получается, да и обновится ли так?
Оставалось палочкой потыкать.. ээ.. попробовать...

Код: Выделить всё

        $c = new CCaptchaAction($this,'captcha'); // 2 обязательных параметра - контроллер и id
        $c->getVerifyCode(true);
Единственный момент - контроллер и id action-а используются при генерации ключа.. т.е. должны совпадать для обращения к "той самой" капче... p.s. Можно, конечно, нужную переменную в сессии обNULLить.
...
Tpona
Сообщения: 222
Зарегистрирован: 2011.06.05, 19:00

Re: CCaptchaAction + ajax

Сообщение Tpona »

Вынужден поднять тему)
Все вроде понятно, можно обработать сценарий ajax как рекомендовано выше, но у меня и \то не проканает:
1) у меня на одной странице 2 капчи одна для регистрации, другая для восстановления пароля. при добавлении второй капчи на странице перестает работать вариант со сценарием ajax.
2) плохо, что не работает аякс валидация капчи впринципе ((
Ответить