Как проверить Google reCaptcha v2 с использованием форм фалкона / вольта?

Как вы проверяете новый reCaptcha Google, используя методы вольта и phalcon?

(Просто хотел поделиться тем, что я сделал, чтобы заставить его работать, см. Ответ ниже, надеюсь, что это поможет …)

    Что тебе понадобится

    • Валидатор (RecaptchaValidator в этом случае)
    • Внедрение Form
    • Реализация Controller (на самом деле никаких изменений здесь нет, но для полноты …)
    • View реализацию
    • (необязательно) Конфигурационные записи для ваших ключей recaptcha и url (лучше / чище)
    • (необязательно) Элемент recaptcha для автоматического рендеринга (если вы предпочитаете метод рендеринга)

    Валидатор

    Валидатор является самой важной частью этого, все другие вещи довольно интуитивно понятны …

     use \Phalcon\Validation\Validator; use \Phalcon\Validation\ValidatorInterface; use \Phalcon\Validation\Message; class RecaptchaValidator extends Validator implements ValidatorInterface { public function validate(\Phalcon\Validation $validation, $attribute) { if (!$this->isValid($validation)) { $message = $this->getOption('message'); if ($message) { // Add the custom message defined in the "Form" class $validation->appendMessage(new Message($message, $attribute, 'Recaptcha')); } return false; } return true; } /******************************************** * isValid - Return Values * ======================= * true .... Ok * false ... Not Ok * null .... Error */ public function isValid($validation) { try { $config = $validation->config->recaptcha; // not needed if you don't use a config $value = $validation->getValue('g-recaptcha-response'); $ip = $validation->request->getClientAddress(); $url = $config->verifyUrl; // or 'https://www.google.com/recaptcha/api/siteverify'; without config $data = ['secret' => $config->secretKey, // or your secret key directly without using the config 'response' => $value, 'remoteip' => $ip, ]; // Prepare POST request $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), ], ]; // Make POST request and evaluate the response $context = stream_context_create($options); $result = file_get_contents($url, false, $context); return json_decode($result)->success; } catch (Exception $e) { return null; } } } 

    Реализация формы (класса)

     class SignupForm extends Form { public function initialize($entity = null, $options = null) { // Name (just as an example of other form fields) $name = new Text('name'); $name->setLabel('Username'); $name->addValidators(array( new PresenceOf(array( 'message' => 'Please enter your name' )) )); $this->add($name); // Google Recaptcha v2 $recaptcha = new Check('recaptcha'); $recaptcha->addValidator(new RecaptchaValidator([ 'message' => 'Please confirm that you are human' ])); $this->add($recaptcha); // Other form fields... } 

    Реализация контроллера

    Несмотря на то, что контроллер такой же, как и в любой другой форме, для полноты здесь приведен пример …

     class SessionController extends \Phalcon\Mvc\Controller { public function signupAction() { $form = new SignupForm(); if ($this->request->isPost()) { if ($form->isValid($this->request->getPost()) != false) { // Add user to database, do other checks, etc. // ... } } $this->view->form = $form; } } 

    Просмотреть реализацию

    Для просмотра вы можете либо просто поместить html туда, либо позволить ему отображаться движком. Если вы хотите, чтобы это было отображено (например, {{ form.render('recaptcha') }} ), вам также нужно будет создать элемент Recaptcha вместо использования одного из значений по умолчанию (см. Последнюю точку в этом ответе для этого).

     ... {{ form('class':'signupForm') }} <fieldset> <div>{{ form.label('name') }}</div> {{ form.render('name') }} {{ form.messages('name') }} <!-- other elements here --> <!-- ... --> <div class="g-recaptcha" data-sitekey="{{ this.config.recaptcha.publicKey }}"></div> {{ form.messages('recaptcha') }} 

    Если вы не хотите использовать конфигурацию для открытого ключа (следующий раздел), просто установите значение ключа data-site на ваш личный (Google reCaptcha) открытый ключ.

    Также не забудьте указать сценарий ( <script src='https://www.google.com/recaptcha/api.js'></script> ) где-нибудь (например, в разделе html head).

    (Необязательно) Config

    Если вы хотите использовать конфигурацию для хранения ваших ключей recaptcha, добавьте также в свой config/config.php

     // config/config.php return new \Phalcon\Config([ 'application' => [ 'controllersDir' => __DIR__ . '/../../app/controllers/', 'modelsDir' => __DIR__ . '/../../app/models/', 'formsDir' => __DIR__ . '/../../app/forms/', 'viewsDir' => __DIR__ . '/../../app/views/', 'pluginsDir' => __DIR__ . '/../../app/plugins/', 'libraryDir' => __DIR__ . '/../../app/library/', 'cacheDir' => __DIR__ . '/../../app/cache/', 'baseUri' => '/', ], // other configs here // ... 'recaptcha' => [ 'publicKey' => 'your public key', 'secretKey' => 'your private key', 'verifyUrl' => 'https://www.google.com/recaptcha/api/siteverify', ], ]); 

    Чтобы иметь возможность доступа к конфигурации в вашем представлении, вам также может потребоваться добавить $di->set('config', $config); к инжектору зависимости (обычно в config/services.php ).

    (Необязательно) Элемент Recaptcha

    Если вы хотите, чтобы ваш recaptcha отображался для вас (вместо того, чтобы вы помещали div непосредственно в представление), вам понадобится отдельный \Phalcon\Forms\Element\

     class Recaptcha extends \Phalcon\Forms\Element { public function render($attributes = null) { return '<div class="g-recaptcha" data-sitekey="' .$this->config->recaptcha->publicKey .'"></div>'; } } 

    Вам также придется изменить свою Form соответственно:

     // ... $recaptcha = new Recaptcha('recaptcha'); $recaptcha->addValidator(new RecaptchaValidator([ 'message' => '...' ])); // ... 

    И, наконец, ваш View :

     {{ form.render('recaptcha') }}