You are here

public function SimpleReCaptchaFormManager::validateCaptchaToken in Simple Google reCAPTCHA 8

Validates form with reCAPTCHA protection enabled.

File

src/SimpleReCaptchaFormManager.php, line 224

Class

SimpleReCaptchaFormManager
Provides helper service used to attach reCaptcha to forms.

Namespace

Drupal\simple_recaptcha

Code

public function validateCaptchaToken(&$form, FormStateInterface &$form_state) {

  // Check if valid token is already present in the session.
  $session_key = 'simple_recaptcha';
  $stored_token = $this->session
    ->has($session_key) ? $this->session
    ->get($session_key) : '';
  $token = $form_state
    ->getValue('simple_recaptcha_token');
  if (strlen($token) > 0 && strlen($stored_token) > 0 && $stored_token == $token) {
    return;
  }
  $message = $form_state
    ->getValue('simple_recaptcha_message');
  if (!$message) {
    $message = $this
      ->t('There was an error during validation of your form submission, please try to reload the page and submit form again.');
  }
  $type = $form_state
    ->getValue('simple_recaptcha_type');
  $config = $this->configFactory
    ->get('simple_recaptcha.config');
  $config_secret_key = $type == 'v2' ? $config
    ->get('secret_key') : $config
    ->get('secret_key_v3');

  // Verify reCAPTCHA token.
  $params = [
    'secret' => $config_secret_key,
    'response' => $token,
  ];
  $url = 'https://www.google.com/recaptcha/api/siteverify';
  if ($config
    ->get('recaptcha_use_globally')) {
    $url = 'https://www.recaptcha.net/recaptcha/api/siteverify';
  }
  $request = $this->client
    ->post($url, [
    'form_params' => $params,
  ]);
  $api_response = Json::decode($request
    ->getBody()
    ->getContents());
  if (!$api_response['success']) {
    $this->logger
      ->get('simple_recaptcha')
      ->notice($this
      ->t('reCAPTCHA validation failed, error codes: @errors', [
      '@errors' => implode(',', $api_response['error-codes']),
    ]));
    $form_state
      ->setError($form, $message);
  }

  // Verify score for reCAPTCHA v3.
  if ($type == 'v3' && isset($api_response['score'])) {
    $desired_score = $form_state
      ->getValue('simple_recaptcha_score');
    $api_score = $api_response['score'] * 100;
    if ($api_score < $desired_score) {
      $this->logger
        ->get('simple_recaptcha')
        ->notice($this
        ->t('reCAPTCHA validation failed, reCAPTCHA score too low: @score (desired score was @desired_score)', [
        '@score' => $api_score,
        '@desired_score' => $desired_score,
      ]));
      $form_state
        ->setError($form, $message);
    }
  }

  // If API response is valid, store current token in the user's session
  // so we won't have to validate this form again.
  if ($api_response['success']) {
    $this->session
      ->set($session_key, $token);
  }
}