Viewing file: ReCaptchaBuilder.php (8.64 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/** * Copyright (c) 2017 - present * LaravelGoogleRecaptcha - ReCaptchaBuilder.php * author: Roberto Belotti - roby.belotti@gmail.com * web : robertobelotti.com, github.com/biscolab * Initial version created on: 12/9/2018 * MIT license: https://github.com/biscolab/laravel-recaptcha/blob/master/LICENSE */
namespace Biscolab\ReCaptcha;
use Illuminate\Support\Arr; use Symfony\Component\HttpFoundation\IpUtils;
/** * Class ReCaptchaBuilder * @package Biscolab\ReCaptcha */ class ReCaptchaBuilder {
/** * @var string */ const DEFAULT_API_VERSION = 'v2';
/** * @var int */ const DEFAULT_CURL_TIMEOUT = 10;
/** * @var string */ const DEFAULT_ONLOAD_JS_FUNCTION = 'biscolabOnloadCallback';
/** * @var string */ const DEFAULT_RECAPTCHA_RULE_NAME = 'recaptcha';
/** * @var string */ const DEFAULT_RECAPTCHA_FIELD_NAME = 'g-recaptcha-response';
/** * @var string */ const DEFAULT_RECAPTCHA_API_DOMAIN = 'www.google.com';
/** * The Site key * please visit https://developers.google.com/recaptcha/docs/start * @var string */ protected $api_site_key;
/** * The Secret key * please visit https://developers.google.com/recaptcha/docs/start * @var string */ protected $api_secret_key;
/** * The chosen ReCAPTCHA version * please visit https://developers.google.com/recaptcha/docs/start * @var string */ protected $version;
/** * Whether is true the ReCAPTCHA is inactive * @var boolean */ protected $skip_by_ip = false;
/** * The API domain (default: retrieved from config file) * @var string */ protected $api_domain = '';
/** * The API request URI * @var string */ protected $api_url = '';
/** * The URI of the API Javascript file to embed in you pages * @var string */ protected $api_js_url = '';
/** * ReCaptchaBuilder constructor. * * @param string $api_site_key * @param string $api_secret_key * @param null|string $version */ public function __construct( string $api_site_key, string $api_secret_key, ?string $version = self::DEFAULT_API_VERSION ) {
$this->setApiSiteKey($api_site_key); $this->setApiSecretKey($api_secret_key); $this->setVersion($version); $this->setSkipByIp($this->skipByIp()); $this->setApiDomain(); $this->setApiUrls(); }
/** * @param string $api_site_key * * @return ReCaptchaBuilder */ public function setApiSiteKey(string $api_site_key): ReCaptchaBuilder {
$this->api_site_key = $api_site_key;
return $this; }
/** * @param string $api_secret_key * * @return ReCaptchaBuilder */ public function setApiSecretKey(string $api_secret_key): ReCaptchaBuilder {
$this->api_secret_key = $api_secret_key;
return $this; }
/** * @return int */ public function getCurlTimeout(): int {
return config('recaptcha.curl_timeout', self::DEFAULT_CURL_TIMEOUT); }
/** * @param string $version * * @return ReCaptchaBuilder */ public function setVersion(string $version): ReCaptchaBuilder {
$this->version = $version;
return $this; }
/** * @return string */ public function getVersion(): string {
return $this->version; }
/** * @param bool $skip_by_ip * * @return ReCaptchaBuilder */ public function setSkipByIp(bool $skip_by_ip): ReCaptchaBuilder {
$this->skip_by_ip = $skip_by_ip;
return $this; }
/** * @param null|string $api_domain * * @return ReCaptchaBuilder */ public function setApiDomain(?string $api_domain = null): ReCaptchaBuilder {
$this->api_domain = $api_domain ?? config('recaptcha.api_domain', self::DEFAULT_RECAPTCHA_API_DOMAIN);
return $this; }
/** * @return string */ public function getApiDomain(): string {
return $this->api_domain; }
/** * @return ReCaptchaBuilder */ public function setApiUrls(): ReCaptchaBuilder {
$this->api_url = 'https://' . $this->api_domain . '/recaptcha/api/siteverify'; $this->api_js_url = 'https://' . $this->api_domain . '/recaptcha/api.js';
return $this; }
/** * @return array|mixed */ public function getIpWhitelist() {
$whitelist = config('recaptcha.skip_ip', []);
if (!is_array($whitelist)) { $whitelist = explode(',', $whitelist); }
$whitelist = array_map(function ($item) {
return trim($item); }, $whitelist);
return $whitelist; }
/** * Checks whether the user IP address is among IPs "to be skipped" * * @return boolean */ public function skipByIp(): bool { return IpUtils::checkIp(request()->ip(), $this->getIpWhitelist()); }
/** * Write script HTML tag in you HTML code * Insert before </head> tag * * @param array|null $configuration * * @return string * @throws \Exception */ public function htmlScriptTagJsApi(?array $configuration = []): string {
$query = []; $html = '';
// Language: "hl" parameter // resources $configuration parameter overrides default language $language = Arr::get($configuration, 'lang'); if (!$language) { $language = config('recaptcha.default_language', null); } if ($language) { Arr::set($query, 'hl', $language); }
// Onload JS callback function: "onload" parameter // "render" parameter set to "explicit" if (config('recaptcha.explicit', null) && $this->version === 'v2') { Arr::set($query, 'render', 'explicit'); Arr::set($query, 'onload', self::DEFAULT_ONLOAD_JS_FUNCTION);
/** @scrutinizer ignore-call */ $html = $this->getOnLoadCallback(); }
// Create query string $query = ($query) ? '?' . http_build_query($query) : ""; $html .= "<script src=\"" . $this->api_js_url . $query . "\" async defer></script>";
return $html; }
/** * Call out to reCAPTCHA and process the response * * @param string $response * * @return boolean|array */ public function validate($response) {
if ($this->skip_by_ip) { if ($this->returnArray()) { // Add 'skip_by_ip' field to response return [ 'skip_by_ip' => true, 'score' => 0.9, 'success' => true ]; }
return true; }
$params = http_build_query([ 'secret' => $this->api_secret_key, 'remoteip' => request()->getClientIp(), 'response' => $response, ]);
$url = $this->api_url . '?' . $params;
if (function_exists('curl_version')) {
$curl = curl_init($url); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_TIMEOUT, $this->getCurlTimeout()); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); $curl_response = curl_exec($curl); } else { $curl_response = file_get_contents($url); }
if (is_null($curl_response) || empty($curl_response)) { if ($this->returnArray()) { // Add 'error' field to response return [ 'error' => 'cURL response empty', 'score' => 0.1, 'success' => false ]; }
return false; } $response = json_decode(trim($curl_response), true);
if ($this->returnArray()) { return $response; }
return $response['success']; }
/** * @return string */ public function getApiSiteKey(): string {
return $this->api_site_key; }
/** * @return string */ public function getApiSecretKey(): string {
return $this->api_secret_key; }
/** * @return bool */ protected function returnArray(): bool {
return ($this->version == 'v3'); }
/** * @return string */ public function getOnLoadCallback(): string {
return ""; } }
|