Для защиты веб форм от ботов есть замечательный, и достаточно известный, сервис reCaptcha, который принадлежит google. Однако бывает так, что на сервере, где вы хотите использовать каптчу от google настройки исходящих подключений настроены очень жёстко. Так случилось и в моей компании, где я сейчас работаю, в результате чего валидация, которая делается на стороне google, не могла быть использована, так как просто не получалось подключиться к серверам. “Пиксы”; резали всё, домены наша версия не поддерживает, поэтому пришлось найти обход этому, добавив всего 1 IP адрес в исключения. И так, поехали.

Модуль _reCaptcha _представляет собой библиотеку для php и называется recaptchalib.php. Внимательно изучив её вы можете найти интересующий вас кусок кода, то что нам интересно находится в функции _recaptcha_http_post(), вот её исходная версия:

/**
 * Submits an HTTP POST to a reCAPTCHA server
 * @param string $host
 * @param string $path
 * @param array $data
 * @param int port
 * @return array response
 */
function _recaptcha_http_post($host, $path, $data, $port = 80) {

        $req = _recaptcha_qsencode ($data);

        $http_request  = "POST $path HTTP/1.0\r\n";
        $http_request .= "Host: $host\r\n";
        $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
        $http_request .= "Content-Length: " . strlen($req) . "\r\n";
        $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
        $http_request .= "\r\n";
        $http_request .= $req;

        $response = '';
        if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
                die ('Could not open socket');
        }

        fwrite($fs, $http_request);

        while ( !feof($fs) )
                $response .= fgets($fs, 1160); // One TCP-IP packet
        fclose($fs);
        $response = explode("\r\n\r\n", $response, 2);

        return $response;
}

Нам нужно поменять всего несколько строчек.

Добавить в начале функции:

$proxy_host = '@@YOUR_WEB_PROXY_HERE';
$proxy_port=3128;

Заменить:

$http_request  = "POST $path HTTP/1.0\r\n";

На:

$http_request  = "POST http://$host$path HTTP/1.0\r\n";

И заменить:

if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {

На:

if( false == ( $fs = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 10) ) ) {

В результате у вас должно получиться следующее:

/**
 * Submits an HTTP POST to a reCAPTCHA server
 * @param string $host
 * @param string $path
 * @param array $data
 * @param int port
 * @return array response
 */
function _recaptcha_http_post($host, $path, $data, $port = 80) {

        $proxy_host = '@@YOUR_WEB_PROXY_HERE';
        $proxy_port=3128;

        $req = _recaptcha_qsencode ($data);

        $http_request  = "POST http://$host$path HTTP/1.0\r\n";
        $http_request .= "Host: $host\r\n";
        $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
        $http_request .= "Content-Length: " . strlen($req) . "\r\n";
        $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
        $http_request .= "\r\n";
        $http_request .= $req;

        $response = '';
        if( false == ( $fs = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 10) ) ) { 
                die ('Could not open socket');
        }

        fwrite($fs, $http_request);

        while ( !feof($fs) )
                $response .= fgets($fs, 1160); // One TCP-IP packet
        fclose($fs);
        $response = explode("\r\n\r\n", $response, 2);

        return $response;
}

Не забудьте поменять значение параметров прокси хоста и порта, поднять прокси, которая вынесена за firewall, ну а в firewall добавить этот ип и порт в исключения. Теперь у вас всё будет работать и будет срабатывать валидация без каких либо проблем.

Так же вы можете скачать уже готовую модифицированную версию библиотеки recaptchalib

Комментарии

comments powered by Disqus