你如何使用volt和phalcon 技术验证新的Google reCaptcha?
(只是想分享我为使其工作所做的工作,请参阅下面的答案,希望对您有所帮助......
你需要什么
- 验证器(在本例中为 RecaptchaValidator)
-
Form
实施 -
Controller
实现(实际上这里不需要更改,但为了完整性...... -
View
实施
( - 可选)验证码密钥和 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') }}
如果您不想为公钥使用配置(下一部分),只需将数据站点密钥的值设置为您的个人(Google reCaptcha)公钥即可。
另外不要忘记在某处(例如在您的 html head 部分)包含脚本 ( <script src='https://www.google.com/recaptcha/api.js'></script>
)。
(可选)配置
如果您想使用配置来存储您的验证码密钥,还要将以下内容添加到您的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
内)。
(可选)验证码元素
如果您希望为您呈现验证码(而不是将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') }}