You are here

function recaptcha_v3_token_validate in reCAPTCHA v3 7

Validate recaptcha token.

Parameters

$element:

Return value

bool

1 call to recaptcha_v3_token_validate()
recaptcha_v3_element_captcha_process in ./recaptcha_v3.module
Need to validate recaptcha v3 token value here, because otherwise in case of failed verification it is no way how to replace captcha element type.

File

./recaptcha_v3.module, line 169
Verifies if user is a human without necessity to solve a CAPTCHA.

Code

function recaptcha_v3_token_validate($element) {
  if (empty($element['#recaptcha_v3_token'])) {
    watchdog('reCAPTCHA v3', 'Missing recaptcha v3 token value', array(), WATCHDOG_ERROR);
    return FALSE;
  }
  if (empty($element['#recaptcha_v3_action']['action'])) {
    watchdog('reCAPTCHA v3', 'Missing recaptcha v3 action value', array(), WATCHDOG_ERROR);
    return FALSE;
  }

  // Use drupal_http_request() to circumvent all issues with the Google library.
  $recaptcha = new \ReCaptcha\ReCaptcha(variable_get('recaptcha_v3_secret_key', ''), new \ReCaptcha\RequestMethod\Drupal7Post());

  // Ensures the hostname matches. Required if "Domain Name Validation" is
  // disabled for credentials.
  if (variable_get('recaptcha_v3_verify_hostname', FALSE)) {
    $recaptcha
      ->setExpectedHostname($_SERVER['SERVER_NAME']);
  }
  $resp = $recaptcha
    ->verify($element['#recaptcha_v3_token'], ip_address());
  if ($resp
    ->isSuccess()) {

    // wrong action id
    if ($resp
      ->getAction() !== $element['#recaptcha_v3_action']['action']) {
      watchdog('reCAPTCHA v3', 'Mismatched site and response actions.', array(), WATCHDOG_ERROR);
      return FALSE;
    }

    // To low user trust score level
    if ($resp
      ->getScore() < $element['#recaptcha_v3_action']['score'] / 10) {
      watchdog('reCAPTCHA v3', 'Response score lower then action threshold score.', array(), WATCHDOG_ERROR);
      return FALSE;
    }

    // Verified!
    return TRUE;
  }

  // Error code reference, https://developers.google.com/recaptcha/docs/verify
  $error_codes = array(
    'action-mismatch' => t('Expected action did not match.'),
    'apk_package_name-mismatch' => t('Expected APK package name did not match.'),
    'bad-response' => t('Did not receive a 200 from the service.'),
    'bad-request' => t('The request is invalid or malformed.'),
    'challenge-timeout' => t('Challenge timeout.'),
    'connection-failed' => t('Could not connect to service.'),
    'invalid-input-response' => t('The response parameter is invalid or malformed.'),
    'invalid-input-secret' => t('The secret parameter is invalid or malformed.'),
    'missing-input-response' => t('The response parameter is missing.'),
    'missing-input-secret' => t('The secret parameter is missing.'),
    'hostname-mismatch' => t('Expected hostname did not match.'),
    'invalid-json' => t('The json response is invalid or malformed.'),
    'score-threshold-not-met' => t('Score threshold not met.'),
    'unknown-error' => t('Not a success, but no error codes received!'),
    'timeout-or-duplicate' => t('Timeout or duplicate!'),
  );
  foreach ($resp
    ->getErrorCodes() as $code) {
    if (!isset($error_codes[$code])) {
      $code = 'unknown-error';
    }
    watchdog('reCAPTCHA v3 web service', '@error', array(
      '@error' => $error_codes[$code],
    ), WATCHDOG_ERROR);
  }
  return FALSE;
}