From e93dba779bfaf4e6bd9820d5e68a2fd8f2267843 Mon Sep 17 00:00:00 2001 From: Dmitry Gladyshev Date: Mon, 17 Apr 2017 11:19:27 +0300 Subject: [PATCH] Recaptcha V2 --- CHANGELOG | 2 ++ README.md | 17 ++++++++++--- src/Client.php | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/Extra.php | 9 ++++--- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7e71509..20b0d12 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +1.2.0 - Add RecapthcaV2 methods + 1.1.0 - Rename RucaptchaException to Exception - Resolve account limit codes on error response - Simplify error messages diff --git a/README.md b/README.md index ac00eab..d4def2e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ rucaptcha-client ================ -PHP-обёртка для сервиса распознавания капчи [rucaptcha.com](https://rucaptcha.com?from=1342124). +Удобная PHP-обёртка для сервиса распознавания капчи [rucaptcha.com](https://rucaptcha.com?from=1342124). Оригинальная документация доступна [по ссылке](https://rucaptcha.com/api-rucaptcha?from=1342124). [![Build Status](https://travis-ci.org/gladyshev/rucaptcha-client.svg?branch=master)](https://travis-ci.org/gladyshev/rucaptcha-client) @@ -10,18 +10,19 @@ PHP-обёртка для сервиса распознавания капчи [ ### Install ```bash -$ composer require --prefer-dist gladyshev/rucaptcha-client "~1.1" +$ composer require --prefer-dist gladyshev/rucaptcha-client "*" ``` or ```php "require": { ... - "gladyshev/rucaptcha-client": "~1.1" + "gladyshev/rucaptcha-client": "*" ... } ``` ### Examples +Больше примеров в папке [examples](/examples). ```php /* Simple */ @@ -106,6 +107,11 @@ Client::getPingbacks() : array; Client::deletePingback(string $uri) : bool; Client::deleteAllPingbacks() : bool; +/* Google Recaptcha V2 */ + +Client::sendRecapthaV2($googleKey, $pageUrl, $extra = []) : int +Client::recognizeRecapthaV2($googleKey, $pageUrl, $extra = []) : string + /* Other */ Client::getLastCaptchaId() : string; @@ -143,4 +149,7 @@ Client::getLoadXml() : \SimpleXmlElement; `header_acao` | integer | 0 | 0 = значение по умолчанию
1 = in.php передаст Access-Control-Allow-Origin: * параметр в заголовке ответа. (Необходимо для кросс-доменных AJAX запросов в браузерных приложениях. Работает также для res.php.) `textinstructions` | string | |Текст, который будет показан работнику. Может содержать в себе инструкции по разгадке капчи. Ограничение - 140 символов. Текст необходимо слать в кодировке UTF-8. `textcaptcha` | string | | Текстовая капча. Картинка при этом не загружается, работник получает только текст и вводит ответ на этот текст. Ограничение - 140 символов. Текст необходимо слать в кодировке UTF-8. -`pingback` | string | | URL для автоматической отправки ответа на капчу (callback). URL должен быть зарегистрирован на сервере. [Больше информации здесь](https://rucaptcha.com/api-rucaptcha#pingback). \ No newline at end of file +`pingback` | string | | URL для автоматической отправки ответа на капчу (callback). URL должен быть зарегистрирован на сервере. [Больше информации здесь](https://rucaptcha.com/api-rucaptcha#pingback). +`recaptcha` | string | | Используется при работе со старым алгоритмом распознования Google Recaptcha V2. [Больше информации здесь](https://rucaptcha.com/api-rucaptcha#solving_recaptchav2_old). +`proxy` | string | | Формат: логин:пароль@123.123.123.123:3128 [Больше информации о прокси здесь.](https://rucaptcha.com/api-rucaptcha#proxies) +`proxytype` | string | | Тип вашего прокси-сервера: HTTP, HTTPS, SOCKS4, SOCKS5. \ No newline at end of file diff --git a/src/Client.php b/src/Client.php index 50deb9d..7ff4ccc 100644 --- a/src/Client.php +++ b/src/Client.php @@ -2,7 +2,9 @@ namespace Rucaptcha; +use GuzzleHttp\RequestOptions; use Rucaptcha\Exception\ErrorResponseException; +use Rucaptcha\Exception\RuntimeException; /** * Class Client @@ -14,6 +16,11 @@ class Client extends GenericClient { const STATUS_OK_REPORT_RECORDED = 'OK_REPORT_RECORDED'; + /** + * @var int + */ + protected $recaptchaRTimeout = 15; + /** * @var string */ @@ -265,6 +272,67 @@ public function deleteAllPingbacks() return $this->deletePingback('all'); } + /* Recaptcha v2 */ + + public function sendRecapthaV2($googleKey, $pageUrl, $extra = []) + { + $this->getLogger()->info("Try send google key (recaptcha) on {$this->serverBaseUri}/in.php"); + + $response = $this->getHttpClient()->request('POST', "/in.php", [ + RequestOptions::QUERY => array_merge($extra, [ + 'method' => 'userrecaptcha', + 'key' => $this->apiKey, + 'googlekey' => $googleKey, + 'pageurl' => $pageUrl + ]) + ]); + + $responseText = $response->getBody()->__toString(); + + if (strpos($responseText, 'OK|') !== false) { + $this->lastCaptchaId = explode("|", $responseText)[1]; + $this->getLogger()->info("Sending success. Got captcha id `{$this->lastCaptchaId}`."); + return $this->lastCaptchaId; + } + + throw new ErrorResponseException($this->getErrorMessage($responseText) ?: "Unknown error: `{$responseText}`."); + } + + /** + * @param string $googleKey + * @param string $pageUrl + * @param array $extra # Captcha options + * @return string # Code to place in hidden form + * @throws RuntimeException + */ + public function recognizeRecaptchaV2($googleKey, $pageUrl, $extra = []) + { + $captchaId = $this->sendRecapthaV2($googleKey, $pageUrl, $extra); + $startTime = time(); + + while (true) { + $this->getLogger()->info("Waiting {$this->rTimeout} sec."); + + sleep($this->recaptchaRTimeout); + + if (time() - $startTime >= $this->mTimeout) { + throw new RuntimeException("Captcha waiting timeout."); + } + + $result = $this->getCaptchaResult($captchaId); + + if ($result === false) { + continue; + } + + $this->getLogger()->info("Elapsed " . (time()-$startTime) . " second(s)."); + + return $result; + } + + throw new RuntimeException('Unknown recognition logic error.'); + } + /** * Match error code by response. * diff --git a/src/Extra.php b/src/Extra.php index d656531..2f62bde 100644 --- a/src/Extra.php +++ b/src/Extra.php @@ -12,14 +12,17 @@ class Extra const QUESTION = 'question'; const NUMERIC = 'numeric'; const CALC = 'calc'; - const MIN_LEN = 'min_len '; - const MAX_LEN = 'max_len '; + const MIN_LEN = 'min_len'; + const MAX_LEN = 'max_len'; const IS_RUSSIAN = 'is_russian'; const SOFT_ID = 'soft_id'; const LANGUAGE = 'language'; - const HEADER_ACAO = 'header_acao '; + const HEADER_ACAO = 'header_acao'; const TEXTINSTRUCTIONS = 'textinstructions'; const TEXTCAPTCHA = 'textcaptcha'; const CONTENT_TYPE = 'content_type'; const PINGBACK = 'pingback'; + const RECAPTCHA = 'recaptcha'; + const PROXY = 'proxy'; + const PROXY_TYPE = 'proxytype'; }