reCaptcha issues : No 'Access-Control-Allow-Or

2020-07-06 03:58发布

问题:

i have some issues in google reCaptcha The captcha is fine, it's show normally, but when I submit it, I have connection issues when I send a POST request to

https://www.google.com/recaptcha/api/verify

here the error log:

XMLHttpRequest cannot load https://www.google.com/recaptcha/api/verify. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3002' is therefore not allowed access. The response had HTTP status code 405.

here my html code:

<div class="form-group" style="margin-bottom: 20px;">
    <div class="text-center center-block">
      <div class="text-center center-block" vc-recaptcha
      tabindex="3"
      theme="white"
      key="model.key"
      lang="en"
           </div>
    <button class="btn" ng-click="submit()">Submit</button>
  </div>
</div>

And this is my controller.js

 $scope.model = {
            key: //THIS IS MY PUBLIC KEY
        };
 $scope.submit = function() {

            var valid;
            var ip;
            $http.jsonp('http://ipinfo.io/?callback=JSON_CALLBACK')
                    .success(function(data) {
                        console.log("stateChangeStart ip = " + data.ip);
                        ip = data.ip;
                    }).then(function() {
                $http({
                    method: 'POST',
                    headers: {
                        'Access-Control-Allow-Origin': '*',
                        'Access-Control-Allow-Methods': 'POST'
                    },
                    url: 'https://www.google.com/recaptcha/api/verify',
                    data: {
                        'privatekey': /* THIS IS MY PRIVATE KEY */,
                        'remoteip': ip,
                        'challenge': vcRecaptchaService.data().challenge,
                        'response': vcRecaptchaService.data().response
                    }

                }).success(function(result, status) {
                    console.log('it work');

                }).error(function(data, status, headers, config) {
                    console.log('error');

                });

            });
        };

I have add headers there, but it always says

No 'Access-Control-Allow-Origin' header is present on the requested resource

can somebody help me? thank you

Update:

I am using chrome and I have enabled CORS in my Chrome with this addon :

enabled CORS in chrome

and now it give me another error:

XMLHttpRequest cannot load https://www.google.com/recaptcha/api/verify. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:3002' is therefore not allowed access. 

and i change my controller.js into this:

 $scope.model = {
            key: //THIS IS MY PUBLIC KEY
        };
 $scope.submit = function() {

            var valid;
            var ip;
            $http.jsonp('http://ipinfo.io/?callback=JSON_CALLBACK')
                    .success(function(data) {
                        console.log("stateChangeStart ip = " + data.ip);
                        ip = data.ip;
                    }).then(function() {
                $http({
                    method: 'POST',
                    headers: {
                        'Access-Control-Allow-Origin': 'http://localhost:3002',
                        'Access-Control-Allow-Methods': 'POST, GET, OPTIONS'
                    },
                    url: 'https://www.google.com/recaptcha/api/verify',
                    data: {
                        'privatekey': /* THIS IS MY PRIVATE KEY */,
                        'remoteip': ip,
                        'challenge': vcRecaptchaService.data().challenge,
                        'response': vcRecaptchaService.data().response
                    }

                }).success(function(result, status) {
                    console.log('it work');

                }).error(function(data, status, headers, config) {
                    console.log('error');

                });

            });
        };

but that error is always shows, please help me.

回答1:

A lot of this stuff is really confusing. We see comments like above that say, "don't validate from client". But if you were like me you were just trying to get it to work first in development and I didn't really care about security at this point. But, I didn't realize that Chrome is more strict than a web server! Chrome will flat out NOT let you do the step that validates the response from Google without doing 2 things first:

  1. Install CORS chrome plugin
  2. add this.headers.append('Content-Type', 'application/x-www-form-urlencoded'); to the headers before sending the post. (at least in angular2)

Obviously afterwards you can't expect all your users to install the Chrome CORS extension plus you don't want to store your secret in the client, that is REALLY BAD. So after you get it working in development, you need to setup a small webserver that will accept this request from your client and forward it to Google, then send the response back to your client.

P.S. other stuff that confused me were people saying to add this.headers.append('Access-Control-Allow-Origin', '*'); but this is a setting you apply when you are setting up a webserver, this has nothing to do with doing requests from a client. I kept trying to apply that to my client side angular http request thinking this would be the be-all-end-all fix.



回答2:

You CAN'T verify your client-side answer with your secret key FROM CLIENT. You must do it from SERVER side only. So, please change the code to go to your server (WebAPI etc.) and just do the POST to Google URI from there. It should work. Otherwise it has no sense to do this check - you are sharing your secret key...



回答3:

In my case I use reCapchaLib and this error fixed: https://github.com/google/recaptcha/blob/1.0.0/php/recaptchalib.php

And use this code PHP:

<?php
error_reporting(E_ALL ^ E_NOTICE);  //variables not declared warning off

// tu clave secreta
$secret = "xxxxxx";   //get from https://www.google.com/recaptcha/
// tu site key
$sitekey = "xxxxxxx";  //get from https://www.google.com/recaptcha/


require_once "recaptchalib.php";

$response = null; 
$reCaptcha = new ReCaptcha($secret);


if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') {
    if ($_POST["g-recaptcha-response"]) {
            $response = $reCaptcha->verifyResponse(
            $_SERVER["REMOTE_ADDR"],
            $_POST["g-recaptcha-response"]
        );
    }

    echo "<h2>Valores del formulario</h2>";

    if (isset($_POST["nombre"])){
        $nombre = $_POST["nombre"];
        echo "<p>nombre: $nombre</p>";  
    }

    if ($response != null && $response->success) {
        echo "<font color='blue'>Captcha Ok!</font>";
    }
    else
        echo "<font color='red'>Error en Captcha!</font>";
}


?>

<!DOCTYPE html>
<html lang="es">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="language" content="es">

    <title>Test Capcha</title>

    <!-- reCAPTCHA Script -->
    <script src='https://www.google.com/recaptcha/api.js'></script>

</head>

<body >

<div class="container">
    <div class="row">
        <div class="col-lg-12 text-center">
            <h2 class="section-heading">Test reCAPTCHA con formulario Post y PHP</h2>
        </div>
    </div>
    <div class="row">
        <div class="col-lg-12">
            <form name="sentMessage" id="contactForm" novalidate method="POST" action="?">
                <div class="row">
                    <div class="col-md-6">
                        <div class="form-group">
                            <input type="text" class="form-control" placeholder="Nombre *" id="nombre" name="nombre" required data-validation-required-message="Ingrese nombre">
                            <p class="help-block text-danger"></p>
                        </div>

                        <div class="clearfix"></div>
                        <div class="col-lg-12 text-center">
                            <div id="success"></div>
                            <center><div class="g-recaptcha" data-sitekey="<?php echo $sitekey; ?>"></div><br></center>
                            <button type="submit" class="btn btn-xl">Enviar Mensaje</button>
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

<script   src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
</body>
</html>