Подтвердить что ты не робот

Имена параметров пользовательской формы reCAPTCHA

Можно ли настроить параметры формы reCAPTCHA (recaptcha_challenge_field и recaptcha_response_field), чтобы они вызывались по-разному?

В принципе, я хочу, чтобы параметр формы recaptcha_challenge_field назывался captchaId и recaptcha_response_field, который будет называться captchaUserResponse.

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

POST/mysite/userSignup

Я не хочу беспокоиться о реализации captcha (reCaptcha или что-то еще в будущем) - извлечение правильных параметров для правильной реализации captcha, я хочу объединить эти имена параметров.

Теперь мой запрос выглядит следующим образом:

POST /mysite/userSignup HTTP/1.1
Host: localhost:80
Connection: keep-alive
Content-Length: 416
Cache-Control: max-age=0
Origin: http://localhost:80
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://localhost:8080/mysite/signup/form.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,hr;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

email:testUser%40gmail.com
username:testUser
password:test
password2:test
forename:Test
surname:User
recaptcha_challenge_field:<google generated challange>
recaptcha_response_field:<user typed captcha answer>
submit:Submit

Но я хочу, чтобы это выглядело так:

POST /mysite/userSignup HTTP/1.1
Host: localhost:80
Connection: keep-alive
Content-Length: 416
Cache-Control: max-age=0
Origin: http://localhost:80
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://localhost:8080/mysite/signup/form.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,hr;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

email:testUser%40gmail.com
username:testUser
password:test
password2:test
forename:Test
surname:User
captchaId:<google generated challange>
captchaUserResponse:<user typed captcha answer>
submit:Submit

Элегантным способом было бы указать те имена параметров формы, как это:

<script>
   var RecaptchaOptions = {
      recaptcha_challenge_field_formparam_name : 'captchaId',
      recaptcha_response_field_formparam_name: 'captchaUserResponse'
   };
</script>

Если это невозможно, какое обходное решение вы предлагаете?

4b9b3361

Ответ 1

Это не должно быть возможным. Возможное решение AFAIU - это добавление новых элементов DOM, которые копируют значения исходных данных непосредственно перед отправкой формы, например:

<!-- the HTML part -->
<input type="hidden" id="captchaId">
<input type="hidden" id="captchaUserResponse">

// the JavaScript (jQuery) part
$('form').submit(function(){
  $('input#captchaId').
    val($('input#recaptcha_response_field').val());
  $('input#captchaUserResponse').
    val($('input#recaptcha_challenge_field').val());
  return true;
})

Ответ 2

Поскольку OP еще не принял никаких ответов, я предоставляю это. Это точно так же, как то, что ищет OP в комментариях этого сообщения: один из ответов

создайте PHP script и поместите его где-нибудь. Я предполагаю, что URI созданной страницы DESIRED_URI. поместите этот код внутри него:

<?php
    header("Content-type: text/javascript");
    /*
    * These are the script parameters
    * You can change them by including desired ones in script URL (as GET params)
    * challenge_field_original: original name of captcha challenge field
    * response_field_original: original name of captcha response field
    * to_challenge_field: the name of the challenge field you want
    * to_response_field: the name of the response field you want
    */
    $params = array(
        /*
        * Defining the defaults of the parameters
        */
        "challenge_field_original" => "recaptcha_challenge_field",
        "response_field_original" => "recaptcha_response_field",
        "to_challenge_field" => "captchaId",
        "to_response_field" => "captchaUserResponse",
    );
    /*
    * Checking for passed GET params to re-fill the parameters with non-default ones (if any)
    */
    if(isset($_GET['challenge']) && $_GET['challenge'] != "") {
        $params["to_challenge_field"] = $_GET['challenge'];
    }
    if(isset($_GET['response']) && $_GET['response'] != "") {
        $params["to_response_field"] = $_GET['response'];
    }
    if(isset($_GET['challenge_original']) && $_GET['challenge_original'] != "") {
        $params["challenge_field_original"] = $_GET['challenge_original'];
    }
    if(isset($_GET['response_original']) && $_GET['response_original'] != "") {
        $params["response_field_original"] = $_GET['response_original'];
    }
?>
/*
* I'm going to find the index of this script tag in the whole document
* So I can find its previous sibling node (the captcha form node)
*/
var scripts = document.getElementsByTagName( 'script' );
var thisScriptTag = scripts[ scripts.length - 1 ];

//now we have the index, good, I'm going to find its previous sibling node
var targetFormTag = (function(element) {
    if(typeof(element.previousElementSibling) == "undefined") {
        var p = element;
        do p = p.previousSibling;
        while (p && p.nodeType != 1);
        return p;
    } else {
        return element.previousElementSibling;
    }
})(thisScriptTag);

//Changing names...
(function(targetForm) {
    var a = targetForm.getElementsByTagName('input');
    var attr = '';
    var toAttr = '';
    for (var i in a) {
        try {
            attr = a[i].getAttribute('name')
        } catch(e) {
            continue;
        }
        switch(attr) {
            case '<?php echo $params["challenge_field_original"]; ?>':
            {toAttr='<?php echo $params["to_challenge_field"]; ?>';break;}
            case '<?php echo $params["response_field_original"]; ?>':
            {toAttr='<?php echo $params["to_response_field"]; ?>';break;}
        }
        a[i].setAttribute('name',toAttr);
    }
})(targetFormTag)

Применение:

Так же просто, как включение script сразу после формы (! это очень важно!). например:

<form><!--form elements--></form>
<script type="text/javascript" src="DESIRED_URI"></script>

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

Побочные примечания:

  • script смехотворно кросс-браузер (IE5 +, Chrome, FF, Android)
  • Вы можете использовать это для любого captcha script, просто укажите имя исходного ввода и имя этого поля ввода в script src.
  • script пытается изменять поля, при сбое он не вызывает никаких ошибок.

Ответ 3

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

Предполагая, что у вас есть следующий вид:

<div id="captcha" class="item recaptcha">
...
<textarea id=custom1 name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input id=custom2 name="recaptcha_response_field" value="manual_challenge" type="hidden" />
<input type="submit" name="submit" value="Submit">
</div>

вы можете изменить имена, используя

document.captcha.custom1.name='captchaId'
document.captcha.custom2.name='captchaUserResponse'

Эти изменения могут быть включены в кнопку отправки прямо или косвенно (вызов другого метода) с помощью события onclick.

Итак, для прямых изменений ваша подача будет:

<input type="submit" name="submit" value="Submit" onclick="document.captcha.custom1.name='captchaId';document.captcha.custom2.name='captchaUserResponse';return true">

Ответ 4

Здесь вы идете, я был в той же ситуации с вами, и вот как я это сделал:

Краткая версия:
здесь добавьте этот атрибут в свою форму, это все, что вам нужно:

EDIT2 - добавлен чистый код Javascript:

чистый-Javascript подход
Протестировано на IE8, FF12 и Chrome:

onsubmit="javascript:(function(p){var a=p.getElementsByTagName('input');var attr='';var toAttr='';for (var i in a){try {attr=a[i].getAttribute('name')} catch(e) {continue;}switch(attr){case 'recaptcha_challenge_field':{toAttr='captchaId';break;}case 'recaptcha_response_field':{toAttr='captchaUserResponse';break;}}a[i].setAttribute('name',toAttr);}p.submit();})(this)"

jQuery:

onsubmit="javascript:(function(p){var f=$(p);$('input[name=recaptcha_challenge_field]',f).attr('name','captchaId');$('input[name=recaptcha_response_field]',f).attr('name','captchaUserResponse');f.submit();})(this)"

E.G:

<form method="post" action="verify.php" onsubmit="javascript:(function(p){var f=$(p);$('input[name=recaptcha_challenge_field]',f).attr('name','captchaId');$('input[name=recaptcha_response_field]',f).attr('name','captchaUserResponse');f.submit();})(this)">
    <?php
    require_once('recaptchalib.php');
    $publickey = "your_public_key"; // you got this from the signup page
    echo recaptcha_get_html($publickey);
    ?>
    <input type="submit" />
</form>

Длинная версия:
Вот что я делаю:

1 - Это фактическая функция javascript, которая отвечает за замену имен входов, здесь ничего особенного:

function(param){
    var form = $(param);
    $('input[name=recaptcha_challenge_field]',form).attr('name','captchaId');
    $('input[name=recaptcha_response_field]',form).attr('name','captchaUserResponse');
    form.submit();
}

2 - Я сделаю указанную функцию анонимной функцией, чтобы я мог ее вызывать через встроенные события HTML (событие onsubmit):

(function(param){...function code...})(this)
  • Отметил, что (this)? в конце нашей анонимной функции? от это, я могу передать дескриптор нашей формы функции.

3 -. Поскольку вам требуется как можно меньше модификации клиента (или вмешательство, которое вы сказали?), я вызову эту анонимную функцию из обработчика событий inline HTML. в нашем случае лучший обработчик onsubmit.

Ну, честно говоря, мне понравилось это решение, надеюсь, он тоже пригодится для вас: D

EDIT1:

Кстати, я не заметил ваших комментариев, если вы хотите сделать это следующим образом:

<form><!--blah blah--></form>
<script type="text/js" src="somewhere"></script>

Это минусы:

  • Вы добавляете дополнительный HTTP-запрос! почему?
  • Вы делаете его асинхронным из события загрузки формы, которое делает его неточным.
  • Вы когда-нибудь думали, что возможно ваш веб-сервер в это конкретное время отклоняет ваш запрос клиента? так что происходит? он разбивает вашу серверную сторону script!
  • Если вы печатаете форму, на стороне сервера, почему вы не делаете эти изменения на стороне сервера?

Ответ 5

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

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

Если вы попытаетесь диктовать, КАК черный ящик выполняет эту проверку, вы уклоняетесь от коробки. Кроме того, если вы в конечном итоге переключитесь на другой плагин captcha, вам также придется гадать с этим.

По этим причинам я предлагаю вам только абстрагировать одну вещь: метод is_human_user (или все, что вы хотите назвать). Все, что вам нужно сделать, это реализовать этот метод для каждого плагина captcha, который вы решите использовать. Для reCAPTCHA кажется, что этот метод вернет recaptcha_challenge_field == recaptcha_response_field. Затем, независимо от того, что проверка просто вызывает is_human_user и слепая, что такое реализация.

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

Ответ 6

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

Учитывая это, я считаю, что лучший способ абстрагировать имя полей - используя переменные на стороне сервера, после получения сообщения формы вы можете сделать:

$captchaId = $_POST["recaptcha_challenge_field"];
$captchaUserResponse = $_POST["recaptcha_response_field"];

Затем передайте это общей функции проверки следующим образом:

recaptcha_generic_check ("PrivateKey", $_SERVER["REMOTE_ADDR"], $captchaId, $captchaUserResponse);

В идеале, вам нужно будет только изменить имя полей, полученных в сообщении (и функции, конечно), и все останется неизменным.