Возникли большие проблемы со вставкой reCaptcha на основе PHP в Shoutbox на основе jQuery.

Это мой первый вопрос на Stack Overflow (однако не первый раз, когда я использую хорошие ответы на вопросы других людей). Я эмпирический программист веб-сайтов, поэтому будьте уверены, я всегда стараюсь до рассвета работать над отсутствием надлежащих инструкций. Вот когда Stack Overflow оказывается очень кстати. Но на этот раз я бился головой о стену PHP более трех или четырех дней. Поэтому прошу помощи в этом вопросе.

По сути, программирование — это чисто математика. Вот почему в конце концов можно понять его язык и то, что происходит. Я дошел до того, что стал очень опытным программистом AS, а потом решил перейти с Flash, попробовать свои силы в HTML с использованием JS и jQuery (так сказать, соревнование) и влюбился. Тем не менее, я скорее любитель в этой области. Но мое отношение к PHP, в частности, совершенно иное: я его не понимаю и не терплю; для меня это санскрит. Может быть, я не использовал его достаточно, чтобы освоиться, но мне кажется, что это не имеет логического смысла, как JS, HTML, AS и ETC. делать.

В любом случае, мое затруднительное положение:

Я создал собственный Shoutbox на основе отличного кода, приведенного здесь: http://yensdesign.com/2009/01/create-a-shoutbox-using-php-and.-ajax-jquery/. Однако код не включает капчу, что делает его полностью уязвимым для спама. Поэтому я сначала разработал простую капчу, состоящую из различных изображений, содержащих числа, которые в сумме дают определенное число. Теперь я пытаюсь проявить фантазию и пытаюсь добавить Google reCaptcha.

ReCaptcha основана на PHP. Sbox использует PHP, но как только файл JS выполняет проверку формы; он использует PHP для окончательного сохранения данных, введенных в базу данных mySql, и извлечения ранее сохраненных данных для отображения. Я пытался поместить PHP-код reCaptcha в эту часть процесса, но он на самом деле не работает, так как все, что он делает, — это блокирует ввод данных и предотвращает их извлечение. Что мне нужно, так это что-то, что останавливает процесс в самом начале, как бы говоря: "Эй! Ты ввел неверную капчу, спам-бот, ты!"

Я также попытался поместить PHP в файл JS. . . В конце концов, после того, как мы потянули за волосы, наткнулись на предложение, в котором говорится: «JS основан на клиенте, а PHP — на сервере». Отличная информация, которую я мог бы найти несколько дней назад. Я-любитель, теперь я понимаю, почему PHP такой суетливый.

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


Я надеюсь, что дал достаточно информации по этому вопросу. Будет полезна обратная связь по моему первому вопросу о переполнении стека. И особенно полезно: любую помощь в разгадке этой тайны вы можете мне подкинуть.

PHP-код reCaptcha выглядит следующим образом:

<?php

$privatekey = "your_private_key";
$resp = recaptcha_check_answer ($privatekey,
       $_SERVER["REMOTE_ADDR"],
       $_POST["recaptcha_challenge_field"],
       $_POST["recaptcha_response_field"]);
if (!$resp->is_valid) {
       // What happens when the CAPTCHA was entered incorrectly
       die ("The reCAPTCHA wasn't entered correctly. Go back and try it again." .
       "(reCAPTCHA said: " . $resp->error . ")");
} else {
       // Your code here to handle a successful verification
}

?>

И это все о reCaptcha, за исключением стиля. Кажется достаточно простым!

Я думаю, что кодов Shoutbox слишком много и они слишком длинные, чтобы включать их сюда и насыщать пост. Но они по ссылке, указанной выше. В основном это HTML Shoutbox, его JS-файл и сохранение и извлечение информации PHP.

Кроме того, для дальнейшего ознакомления я прилагаю ссылку на RAR-файл, содержащий мою работу над Shoutbox, как есть, на данный момент. Как вы увидите, внизу страницы есть прелоадер. Он должен отключиться, когда появится список предыдущих сообщений. Это не работает из-за проклятого PHP, который я неуклюже поместил в файл JS, который, без сомнения, возвращается и ошибка, которая останавливает последовательность JS. Если вы комментируете PHP или удаляете его, то последовательность должна быть завершена, и по крайней мере сообщение "can't find db... bla bla" должно появиться после исчезновения предварительного загрузчика, что означает, что Shoutbox функционал (но без капчи).

И RAR-файл, вуаля: (Больше не доступен)

Заранее большое спасибо за терпение и за любую помощь, которую вы можете отправить мне!


ИЗМЕНИТЬ 1:

Хорошо, теперь идет обновление, следуя инструкциям Дж. Бруни для упражнения, подробно описанного ниже.

Итак, следуя рекомендациям Дж. Бруни, при условии, что я их правильно понял, я вынул только iframe. Я оставил остальную часть reCaptcha нетронутой, так как она излишня в этом упражнении (кроме того, мне нужно изображение Captcha, чтобы проверить, работает ли эта вещь на самом деле). Как видите, form изначально не настроен для публикации в конкретный выходной файл (причина в том, что для этого у него есть JS-файл), но, как следует из упражнения, рекомендованного Дж. Бруни, я установил для него значение action="shoutbox.php". . Это означает, что теперь он полностью обходит файл JS.

Тестирование: я получаю сообщения о НЕПРАВИЛЬНЫХ СЛОВАХ и ПРАВИЛЬНЫХ СЛОВАХ. Дж. Бруни закодирован в исходный PHP-код reCaptcha соответственно, поэтому сейчас все работает идеально, по крайней мере, в отношении reCaptcha.

Однако, как я уже сказал, файл JS полностью игнорируется. В одном из первых ночных тестов я попробовал что-то похожее на то, что предлагает Дж. Бруни. Я попытался вернуть утверждение true/false с помощью этого кода reCaptcha в верхней части файла PHP, чтобы его можно было обусловить вместе с true/false, возвращаемым функцией проверка заполнения всех полей (на стороне клиента, в файле JS), чтобы продолжить, если все верно, или вернуть сообщение об ошибке, если любое неверно. Проблема, с которой я столкнулся там, как вы, наверное, догадались, но я понял только позже, заключалась в том, что одна проверка выполняется на стороне клиента, а другая — на стороне сервера; как вы можете соединить их обоих? (Если вы вообще можете.) Мой вопрос здесь будет таким: Есть ли способ «параллельно» запустить и PHP, и JS, а затем объединить их соответствующие результаты? Уже есть это кажется невозможным; будучи на стороне клиента, он звучит немедленно, а другой, на стороне сервера, звучит удаленно.

Более того, более проницательный программист в этот момент скажет: зачем заботиться об обеих проверках по отдельности? Кажется очень грязным и ненужным; они оба могут быть в PHP. Увы! Дело в том, что, хотя я знаю, как отправить текстовые переменные ввода формы прямо в файл PHP, я понятия не имею, как перевести на PHP все остальное! Даже не знаю, можно ли это перевести. На самом деле, если бы у меня был выбор, я бы предпочел найти способ сделать все это JS. Но вот что мудро отмечает Дж. Бруни:

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

Итак, после того, как первое ночное упражнение, которое я объяснил выше, закончилось фиаско, я попытался настроить остальную часть кода Shoutbox.php на функцию reCaptcha, возвращающую true. Если он вернет false, код PHP на этом остановится. Однако это означало, что никакие предыдущие сообщения не будут отображаться в Shoutbox до отправки новой формы; и даже в этом случае это будет обусловлено эффективной отправкой формы (это означает, что reCaptcha была введена правильно). Если бы форма вернула false, то ничего бы не произошло, кроме перезагрузки страницы, что, согласитесь, нецелесообразно по многим причинам. С другой стороны, разделение обеих частей PHP-кода, делающее один запуск независимым от условия reCaptcha, а другой — условным, на самом деле не имело большого значения.

Тогда-то я и попытался вставить PHP-проверку reCaptcha в JS-файл, что мне показалось единственным выходом. И все мы знаем, чем это закончилось! Это привело меня сюда и к твоей милости. И, как мудро заметил Дж. Бруни, я не подумал о том, что моя клиентская сторона частного идентификатора предложила его миру незащищенным.

Итак, после предложенного Дж. Бруни упражнения у меня теперь есть, что reCaptcha работает нормально сама по себе. Если форма размещается непосредственно в файле PHP, и если части файла JS, которые отвечают за сбор значений формы и проверку их правильности, транскрибируются в файл PHP, то я думаю, что Sbox может работать на скорости. начальный уровень. Но прямо сейчас и без reCaptcha Sbox работает на 100%, все причудливое и все такое. Должен быть способ вставить эту чертову reCaptcha, и Sbox по-прежнему будет работать на высшем уровне. Теперь мне нужно выяснить, как сделать своего рода «обходной путь», который позволит файлу JS также творить чудеса, в то время как PHP делает свою работу. Хотя, если честно, я не уверен, что практичнее: сначала проверить, заполнены ли формы, и вернуть ошибку, если они не заполнены, прежде чем даже проверить, правильно ли введена reCaptcha, или наоборот. Их всегда можно сложить вместе, как я пытался сделать в первом примере ночного судебного разбирательства, о котором я рассказал вам выше; но, конечно, гораздо интереснее проверять их по отдельности, чтобы вы могли сказать своему пользователю, где именно он ошибается. Что я знаю, так это то, что кажется более практичным остановить отправку формы в самом первом случае, при обнаружении ошибки или неправильного ввода либо в форме, либо в reCaptcha, вместо того, чтобы позволить данным пройти весь путь до базы данных. дверь перед проверкой ее достоверности. Может быть, это спорный вопрос, принимая во внимание, что все это делается за доли секунды, но это просто звучит беспорядочно. Как вы думаете?

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

ПРИМЕЧАНИЕ: Кстати, я понял (по крайней мере, при публикации прямо на PHP), что reCaptcha нуждается в дополнительном скрипте, который требует обновления каждый раз, когда страница возвращается любым другим способом. чем путем обновления, скажем, нажав НАЗАД после того, как результат будет напечатан. В противном случае изображение капчи остается прежним, но, по-видимому, reCaptcha считает, что оно показывает еще одну проблему; если вы попытаетесь ответить на ту же reCaptcha с тем же изображением, которое, как вы, возможно, уже знаете, будет правильным, оно вернет результат false. Для меня это означает, что вызов всегда перезагружается автоматически, но по какой-то причине в этом конкретном случае изображение остается неизменным. Просто на голову.


ИЗМЕНИТЬ 2

Хорошо, как заметил Дж. Бруни, мы оба проглядели "!" в операторе if в PHP-файле. Теперь это исправлено.

ОДНАКО... да, однако возникает еще одна проблема.

Хм. Оператор if был исправлен, и теперь он возвращает предупреждение «неверная капча». Но по какой-то причине reCapthca всегда возвращает «неправильно», несмотря ни на что. Вчера форма всегда печаталась, даже если капчи не было или вставлена ​​неверная капча, потому что оператор if, как заметил Бруни, был настроен на возврат положительного результата при неправильном вводе капчи, и в этом случае форма будет продолжаться. и напечатать, если капча была неправильной (но не если она была правильной). Он всегда был неверным, поэтому он все время печатался. Исправление утверждения if для возврата положительного значения при правильном вводе проверки по слову показало, что проверка всегда возвращает неправильный ответ, потому что теперь вы всегда получаете предупреждение «неправильная проверка». Так что эта конкретная проблема должна быть где-то в другом месте.

Теперь, как я неоднократно заявлял, я практически потерялся в PHP. Поэтому я не мог сказать, правильно ли выражение if/else в PHP. Но если мне помогает мой другой опыт, мне кажется, что оператору if в JS-файле может не хватать чего-то, что заставляет его предупреждать и останавливать остальную часть функции complete: function(data), потому что мне кажется, что остальная часть функции complete: function(data) всегда воспроизводится. В любом случае мне кажется странным не помещать alert() в скобки в результате утверждения if. Может быть, даже если оператор if неверен, все равно alert() и остальная часть функции воспроизводятся, потому что ей нужны скобки... Но поскольку эта часть - AJAX, я могу говорить тарабарщину и лаять не на то дерево. Пожалуйста, поправьте меня, если я ошибаюсь.

Я постараюсь решить ее и отпишусь, где скрывалась проблема. И когда я получу 100% работающий Sbox, я опубликую конечный продукт здесь, чтобы он был доступен для всех, кто может столкнуться с такой же или похожей проблемой.


ИЗМЕНИТЬ 3

Моя интуиция была верна в том, что оператор if в функции complete: function(data) должен быть заключен в скобки; в противном случае предупреждение «неверная капча» будет появляться всегда, независимо от того, возвращает ли проверка PHP reCaptcha «неправильно» или нет.

complete: function(data){
if (data.responseText == 'wrong') {
alert('Wrong captcha');
}
messageList.html(data.responseText);
updateShoutbox();
...

P.S. Не удается правильно отобразить коды на этой странице... Я пытаюсь следовать правилам форматирования справа, но безрезультатно.

П.П.С. ReCaptcha по-прежнему всегда возвращает «неправильно». Будет обновлять прогресс, когда он есть.


person user1247075    schedule 03.03.2012    source источник


Ответы (1)


Однажды я попытался загрузить reCaptcha с помощью AJAX. Это не сработало. Я не слишком старался, так как мог просто не использовать AJAX, что я и сделал. Тот же самый код, который не работал через AJAX, работал в простой простой форме.

Кроме того, как вы говорите, reCaptcha не основана на PHP. Вы можете использовать с ним любой серверный язык (включая PHP).


Я просмотрела ваш файл index.php. Прежде чем настраивать внешний вид, давайте попробуем выполнить базовую работу. Я видел сочетание тегов iframe и script. Все, что вам нужно, очень просто (при условии, что ваш открытый ключ — это строка, начинающаяся с «6Ld_b8»):

<input type="text" id="recaptcha_response_field" name="recaptcha_response_field" />
<script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k=6Ld_b84SAAAAAAv1Ds1vYHxQjyoowiCPkARtvB2W"></script>

Удалите iframe. На данный момент вы можете удалить все, что связано с recaptcha.

Итак, у вас есть form, который будет опубликован на shoutbox.php. Затем на мгновение добавьте код, который вы вставили в свой вопрос, в начало этого файла. Вам необходимо включить recaptchalib.php и заменить закрытый ключ reCaptcha на "your_private_key". Итак, код будет выглядеть так:

// put this on top of shoutbox.php
include "recaptchalib.php";
$privatekey = "your_private_key"; // change this here to your reCaptcha private key!
$resp = recaptcha_check_answer ($privatekey, 
       $_SERVER["REMOTE_ADDR"],
       $_POST["recaptcha_challenge_field"],
       $_POST["recaptcha_response_field"]);
if (!$resp->is_valid) {
       echo '<b>WRONG WORDS!</b>';
} else {
       echo '<b>CORRECT WORDS! GREAT!</b>';
}
exit();

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


ИЗМЕНИТЬ 1

Вам просто нужно добавить проверку reCaptcha в правильном месте внутри shoutbox.php. Кажется, это может быть в части «вставка регистра» или внутри функции «insertMessage»:

    case "insert":
        include "recaptchalib.php";
        $privatekey = "your_private_key"; // change this here to your reCaptcha private key!
        $resp = recaptcha_check_answer ($privatekey, 
            $_SERVER["REMOTE_ADDR"],
            $_POST["recaptcha_challenge_field"],
            $_POST["recaptcha_response_field"]);
        if ($resp->is_valid)
            echo insertMessage($_POST['nick'], $_POST['message']);
        break; 

Вы видели complete: function(data){ строк в коде javascript? Это один из вариантов вызова функции $.ajax. Он указывает функцию, которая будет выполняться после выполнения PHP-кода и отправляет свой ответ обратно в браузер. Ответ от сервера будет находиться где-то в параметре data, который вы можете использовать. Если вы хотите отобразить сообщение для пользователя, предупреждающее его в случае «неправильных слов» для капчи, вам необходимо:

  1. Вернуть что-то со стороны сервера (код PHP):

        if ($resp->is_valid)
            echo insertMessage($_POST['nick'], $_POST['message']);
        else
            echo 'wrong';
    
  2. Используйте этот возврат на стороне клиента (код JS):

    $.ajax({  
        type: "POST", url: "shoutbox.php", data: "action=insert&nick=" + nick + "&message=" + message,  
        complete: function(data){
            if (data.responseText == 'wrong')
                alert('Incorrect captcha words! Try again.');
            messageList.html(data.responseText);  
            updateShoutbox();  
            //reactivate the send button  
            $("#send").attr({ disabled:false, value:"Shout it!" });  
        }  
     });  
    

И да, вам нужно будет перезагрузить reCaptcha (для кнопки НАЗАД и в случае отправки - успешно или нет). Для кнопки «Назад» вы можете установить HTTP-заголовок «Expires» с помощью PHP или «мета»-тега HTML, заставив страницу перезагрузиться. В другом случае (после отправки формы ajax) вы можете запросить новую задачу, заменив HTML с помощью JavaScript/jQuery. Оберните задачу в div:

<div id="challenge">
    <input type="text" id="recaptcha_response_field" name="recaptcha_response_field" />
    <script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k=6Ld_b84SAAAAAAv1Ds1vYHxQjyoowiCPkARtvB2W"></script>
</div>

И «перезагрузить» его при необходимости:

function reloadCaptcha(){
    $('#challenge').html('<input type="text" id="recaptcha_response_field" name="recaptcha_response_field" /><script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k=6Ld_b84SAAAAAAv1Ds1vYHxQjyoowiCPkARtvB2W"></script>');
}
person J. Bruni    schedule 03.03.2012
comment
Да, вы правы, reCaptcha не обязательно PHP-ориентированная, моя ошибка. Я хотел сказать, что единственный код, предоставленный ими, — это PHP-код, который я включил в свой пост. Чтобы использовать reCaptcha, на своем веб-сайте они предлагают его в виде плагина, скажем, для WordPress или MediaWiki, и код PHP, как показано здесь: ссылка Использование reCAPTCHA с PHP. Теперь, как вы говорите, это не обязательно основано на PHP, поэтому, если бы был способ перевести то, что делает этот PHP-код, скажем, в JS, это тоже отлично сработало бы. - person user1247075; 03.03.2012
comment
@ user1247075: я добавил больше к своему ответу выше - person J. Bruni; 03.03.2012
comment
Вам нужен некоторый серверный код, потому что вы не можете показать свой закрытый ключ публике. Вам нужен ответ, введенный пользователем, и подтвердите с помощью Google, если это правильный ответ на вызов. Вы просто не можете делегировать это самому пользователю (на стороне клиента) - технический пользователь очень легко обойдет всю проверку, если все делается на стороне клиента, а не на стороне сервера... - person J. Bruni; 03.03.2012
comment
@J Bruni: Спасибо за ответ! Я редактирую свой вопрос выше, чтобы включить результаты рекомендованного вами теста. Пожалуйста, проверьте это, если можете, и дайте мне знать, если у вас есть какие-либо дополнительные сведения. - person user1247075; 06.03.2012
comment
@ user1247075: Включил в свой ответ больше информации. :) - person J. Bruni; 06.03.2012
comment
@J Bruni: Еще раз спасибо! x2 для другого быстрого ответа. Я проверю, что у вас получилось за эти пару дней, и вернусь сюда, чтобы опубликовать свой прогресс. - person user1247075; 06.03.2012
comment
@J Bruni: я обновил свой код вашими рекомендациями, похоже, они должны работать, но что-то пошло не так. Не знаю, неправильно ли я что-то истолковал или неправильно вставил, или, возможно, другая часть кода переопределяет новую часть; дело в том, что рекапча обойдена. Если вы заполните формы, независимо от того, пуста ли reCaptcha или заполнена неправильно, сообщение будет отправлено в чат. Если вы нажмете «Отправить сообщение», ничего не заполнив, reCaptcha перезагрузится, и все, jaja (по крайней мере, теперь это работает!). (продолжает...) - person user1247075; 07.03.2012
comment
@J Bruni: (часть 2) Я оставляю вам здесь RAR с отредактированным кодом, надеюсь, вы сможете отсканировать его и найти, где что-то пошло не так. Я проверял это много, много раз и не могу найти возможную ошибку. Возможно, я устал и не замечаю очевидную ошибку. В любом случае, еще раз спасибо за вашу помощь, Дж. Бруни, без нее я не думаю, что смог бы так продвинуться в чате, по крайней мере, в течение очень долгого времени! Здесь: alessandropucci.com/dload/sboxwcaptcha2.rar - person user1247075; 07.03.2012
comment
Кажется, мы оба устали, потому что ошибка очевидна: if ($resp->is_valid) означает, что ответ правильный, а if (!$resp->is_valid) означает, что ответ недействителен... так что просто удалите ! оттуда, и это будет работать (уже удалено в моем ответе выше). - person J. Bruni; 07.03.2012
comment
Да, это было довольно очевидно! Но настолько очевидно, что его легко не заметить. Аргумент против ночного программирования. Спасибо еще раз! - person user1247075; 08.03.2012