#php #laravel #recaptcha-v3
Вопрос:
Я реализовал Google RecaptchaV3 для формы регистрации пользователя (код для этой формы был создан make:auth
в предыдущей версии Laravel (я думаю, что это было около 5.6)).
Регистрация пользователя (и капча) работают нормально, если предоставленные значения формы проходят процесс проверки, в противном случае страница просто перезагружается (как и должно быть), но с пустой переменной $errors.
Если я удалю JS-код Recaptcha со страницы, отправка формы с недопустимыми данными правильно обновит страницу, а переменная $errors будет содержать сообщения об ошибках для каждого недопустимого поля.
Клиент:
//Just for testing..
{{ print_r($errors) }}
...
<form method="POST" id="dm-register-form" action="{{ route('register') }}">
...
<input type="hidden" id="captcha-token" name="g-recaptcha-response" value="">
<button type="button" id="btn-submit-registration">Submit</button>
...
<script>
document.getElementById('btn-submit-registration').addEventListener('click', (e) => {
e.preventDefault();
grecaptcha.ready(function() {
grecaptcha.execute('{{ config('app.captcha_site_key') }}', {action: 'register'}).then(function(token) {
document.getElementById('captcha-token').value = token;
document.getElementById('dm-register-form').submit();
});
});
});
</script>
Сервер:
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return IlluminateContractsValidationValidator
*/
protected function validator($request) {
return Validator::make($request->all(), [
'name' => ['required', 'string', 'max:255'],
'surname' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255',],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'g-recaptcha-response' => ['required', new CaptchaV3($request->ip(), 'register')],
]
}
public function register(Request $request) {
$this->validator($request)->validate();
event(new Registered($user = $this->create($request->all())));
...
}
<?php
namespace AppRules;
use IlluminateContractsValidationRule;
use ReCaptchaReCaptcha;
class CaptchaV3 implements Rule {
private $remote_ip;
private $actionName;
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct($remote_ip, $actionName) {
$this->remote_ip = $remote_ip;
$this->actionName = $actionName;
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value) {
$recaptcha = new ReCaptcha(config('app.captcha_secret_key'));
$resp = $recaptcha->setExpectedAction($this->actionName)
->setScoreThreshold(0.5)
->verify($value, $this->remote_ip);
return $resp->isSuccess();
}
/**
* Get the validation error message.
*
* @return string
*/
public function message() {
return 'Captcha Failed.';
}
}
EDIT: After further testing, I found out that the problem only happens in the local environment (using xampp and http), while on the live server which uses https, it works.
On the local enviroment I get this warning in console when the page refreshes (after a submit with invalid data) :
Set-Cookie header is ignored in response from url: http://xampp.app.dm/en/register. Cookie length should be less than or equal to 4096 characters.
Another difference from the live server, is that in local I use those env settings :
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=cookie
находясь в прямом эфире, я использую memcached :
CACHE_DRIVER=memcached
QUEUE_CONNECTION=redis
SESSION_DRIVER=memcached