简体   繁体   中英

Post custom HANDLER URL reCAPTCHA

I am trying to implement reCAPTCHA validation via Marketing Cloud - cloud page.

I have used this guide to do that: https://ampscript.xyz/how-tos/how-to-implement-google-recaptcha-on-marketing-cloud-forms/

What I want to do is to create a post request instead of use the action form property.

My Clint side script:

<!doctype html>
<html>
<head>
 <meta charset="utf-8">
 <title></title>
 <meta name="description" content="">
 <meta name="viewport" content="width=device-width, initial-scale=1">

 <script src="https://www.google.com/recaptcha/api.js"></script>
</head>

<body>



<form id="form" >
    <label>Email: </label>
    <input type="email" name="EmailAddress">
    <div 
        class="g-recaptcha" 
        data-sitekey="XXXXXXXXXXXXXXXXXXXXXX" 
        data-callback="grecaptchaCallback" 
        data-size="invisible"
    ></div>
    <br>
    <button>Send</button>
</form>


<script>
    var form = document.getElementById('form');

    form.addEventListener('submit', grecaptchaValidate);

    function grecaptchaCallback() {
        return new Promise(function (resolve, reject) {
            if (grecaptcha.getResponse() !== '') {
                var x=grecaptcha.getResponse();
                console.log(x);
                var xhttp = new XMLHttpRequest();
                xhttp.open("POST", "https://pub.s7.exacttarget.com/jnmlkgsfquv", true);
                xhttp.setRequestHeader("Content-type",  'text/html',['Accept-Encoding'], ['identity'] );
                xhttp.send();
                http.onreadystatechange =  function() {
        if (this.readyState == 4 && this.status == 200) {
        
        var response=this.responseText;
        console.log(response);
        response=response.split("<script>");
        console.log(response);
        console.log(response[0].trim());
    }

}
            }
            grecaptcha.reset();
        })
    }

    function grecaptchaValidate(e) {
        e.preventDefault();
        grecaptcha.execute();
    }
</script>


</body>
</html>
    </script>
</body>
</html>

And this is my server-side script:


<script runat="server">
 
    Platform.Load("core", "1.1.1");

    try {

        var g_recaptcha_response = Request.GetFormField("g-recaptcha-response");
        var secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";
        var payload = "secret=" + secret + "&response=" + g_recaptcha_response;
  var contentType = "application/x-www-form-urlencoded";
  var endpoint = "https://www.google.com/recaptcha/api/siteverify";
        var req = HTTP.Post(endpoint, contentType, payload);

        if (req.StatusCode == 200) {

            var resp = Platform.Function.ParseJSON(String(req.Response));

            if (!resp.success) throw "Wrong reCAPTCHA";

        } else {
            throw "reCAPTCHA API error";
        }

        /// DO SOMETHING

        Write(Stringify(resp));

    } catch (error) {
        Write(Stringify({ status: "Error", message: error }));
    }

</script>

The error I get when I send the request is:

{"status":"Error","message":"Wrong reCAPTCHA"}




<script>(function(a,m,i,g,o,s){o=a.createElement(g);s=a.getElementsByTagName(i)[0];o.src=m.origin+m.pathname+"/_t?eventType=CLOUDPAGESVISIT";o.width=0;o.height=0;o.style.display="none";s.appendChild(o);})(document,window.location,"body","img");</script>
    <script src="https:&#x2F;&#x2F;7231513.collect.igodigital.com&#x2F;collect.js"></script>
    <script>
        if (_etmc && typeof _etmc.push === 'function') {
            _etmc.push(['setOrgId', '7231513']);
            _etmc.push(['trackPageView']);
        }
    </script>

Another conclusion I came to- If I insert manually the value that I received from the client-side from x object (the grecaptcha.getResponse() ) The response correct:

 {"success":true,"challenge_ts":"2020-07-29T09:30:03Z","hostname":"pub.s7.exacttarget.com"}

I would love to get an idea of how I create the request from the client-side to the server-side page according to post I am initiating?

Is there anything I'm missing? Or maybe I'm not working correctly?

Edit:

The problem was with the payload at server-side page, because the variable g_recaptcha_response was null.

My workaround is to catch the variable with query string variable:


%%[
  set @x = RequestParameter("x")
]%%
<script runat="server">
 
    Platform.Load("core", "1.1.1");
  var x = Variable.GetValue("@x");  
 

    try {

 
      //  var g_recaptcha_response = Request.GetFormField("g-recaptcha-response");
      
        var secret = "XXXXXXXXXXXXXXXXXXXXXXXXX";
        var payload = "secret=" + secret + "&response=" + x;
  var contentType = "application/x-www-form-urlencoded";
  var endpoint = "https://www.google.com/recaptcha/api/siteverify";
        var req = HTTP.Post(endpoint, contentType, payload);

        if (req.StatusCode == 200) {

            var resp = Platform.Function.ParseJSON(String(req.Response));

            if (!resp.success) throw "Wrong reCAPTCHA";

        } else {
            throw "reCAPTCHA API error";
        }

        /// DO SOMETHING

        Write(Stringify(resp));

    } catch (error) {
        Write(Stringify({ status: "Error", message: error }));
    }

</script>

Because there is no way to catch URL data on SSJS I using AMPscript to catch x and pass it to payload, now I get a success response.

But I'm not sure if there have any security problem in this way.

First of all, you need to create your Cloud page using the Content Builder option. This will remove the script tags in your response.

Second, you are sending your data in the content type of text/html , try using application/x-www-form-urlencoded instead.

I believe, your Form Handler doesn't capture the g-recaptcha-response because it can't be retrieved with Request.GetFormField when you are sending text/html content type.

Please have a look at this article: https://ampscript.xyz/how-tos/perform-an-http-request/

Otherwise, use Axios for your client-side requests: https://github.com/axios/axios

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM