I have been unable to integrate reCAPTCHA with Cloud Armour when using an Action Token.
Firstly, The example for using Session tokens to display a challenge page at this codelab is working as expected.
The challenge page displays when clicking the median score link
<!doctype html>
<html>
<head>
<title>ReCAPTCHA Testing</title>
<script
src="https://www.google.com/recaptcha/enterprise.js?render=<SESSION_TOKEN>&waf=session"></script>
</head>
<body>
<h1>Main Page</h1>
<p><a href="/good-score.html">Visit allow link</a></p>
<p><a href="/bad-score.html">Visit blocked link</a></p>
<p><a href="/median-score.html">Visit redirect link</a></p>
</body>
</html>
Next, I am trying to implement an Action Token. So I updated the the sample code from the codelab following the documentation here.
- Created an Action token with the same test score as the Session token in the codelab
- Updated the Cloud Armour rule to reference
token.recaptcha_action.score
- Updated the <script scr... HTML removing
&waf=session
and referencing the new Action token - Added the Javascript as per the sample code in the documentation.
<!doctype html>
<html>
<head>
<title>ReCAPTCHA Testing</title>
<script
src="https://www.google.com/recaptcha/enterprise.js?render=<ACTION_TOKEN>"></script>
<script>
function onSuccess(token) {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://<LB_IP>/median-score.html', false);
xhr.setRequestHeader("X-Recaptcha-Token", token);
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
// Display the response, it could be a reCAPTCHA challenge
// page based on your Google Cloud Armor security rule settings.
// I can see that xhr.responseText is a HTML document referencing the challenge page
document.open();
document.write(xhr.responseText)
document.close();
}
};
xhr.send(null);
}
grecaptcha.enterprise.ready(function () {
document.getElementById("challenge-link").onclick = () => {
grecaptcha.enterprise.execute('<ACTION_TOKEN>', {}
).then(onSuccess).catch(err => {
console.log('Something went wrong');
console.error({ err });
})
};
});
</script>
</head>
<body>
<h1>Main Page</h1>
<p><a href="/good-score.html">Visit allow link</a></p>
<p><a href="/bad-score.html">Visit blocked link</a></p>
<p><a href="#" id="challenge-link">Visit redirect link</a></p>
</body>
</html>
The result looks like this - The challenge is never displayed
I can see the result of xhr.responseText
is a HTML document referencing reCAPTCHA so it is expecting to be display somewhere. I have tried all combinations of setting the xhr.responseText
to innerHTML
of a div, to within an iframe
however have not been successful.
How can the challenge page be displayed when using the XMLHttpRequest() approach suggested in the documentation?