I'm trying to set up reCaptcha Enterprise in a React/Node.js application. I have successfully set up the reCaptcha to work on the frontend and it is generating a token and passing it to the backend for assessment. The problem I can't seem to get around is the Node.js assessment example code from Google breaks, giving a the message SyntaxError: Unexpected token '.'. Specifically, this seems to happen when creating a new RecaptchaEnterpriseServiceClient. I suspect there might be an issue with authentication using Application Default Credentials, but I haven't seen any evidence of errors in the backend logging.
First, in the Google Cloud Console I give my IAM user roles for reCAPTCHA Enterprise Admin and reCAPTCHA Enterprise Agent.
I'm running the backend in Docker. I use the gcloud cli to authenticate my IAM user on my host machine, generate the ADC and mount it on the backend container using docker compose.
...
volumes:
- $HOME/.config/gcloud/application_default_credentials.json:/gcp/creds.json:ro
...
The json credentials look something like this.
{
"account": "",
"client_id": "764....apps.googleusercontent.com",
"client_secret": "d-F.....",
"quota_project_id": "my-project-name",
"refresh_token": "1//04k.....",
"type": "authorized_user",
"universe_domain": "googleapis.com"
}
I set the environment variable Google uses to find the ADC.
GOOGLE_APPLICATION_CREDENTIALS="/gcp/creds.json"
I add the example assessment method to my backend code.
const { RecaptchaEnterpriseServiceClient } = require('@google-cloud/recaptcha-enterprise');
const createAssessment = async (assessObj) => {
const { projectID, recaptchaKey, token, recaptchaAction } = assessObj;
// console.log("projectID", projectID, "recaptchaKey", recaptchaKey, "token", token, "recaptchaAction", recaptchaAction)
// Create the reCAPTCHA client.
// TODO: Cache the client generation code (recommended) or call client.close() before exiting the method.
const client = new RecaptchaEnterpriseServiceClient();
const projectPath = client.projectPath(projectID);
// Build the assessment request.
const request = ({
assessment: {
event: {
token: token,
siteKey: recaptchaKey,
},
},
parent: projectPath,
});
const [ response ] = await client.createAssessment(request);
// Check if the token is valid.
if (!response.tokenProperties.valid) {
console.log(`The CreateAssessment call failed because the token was: ${response.tokenProperties.invalidReason}`);
return null;
}
// Check if the expected action was executed.
// The `action` property is set by user client in the grecaptcha.enterprise.execute() method.
if (response.tokenProperties.action === recaptchaAction) {
// Get the risk score and the reason(s).
// For more information on interpreting the assessment, see:
// https://cloud.google.com/recaptcha-enterprise/docs/interpret-assessment
console.log(`The reCAPTCHA score is: ${response.riskAnalysis.score}`);
response.riskAnalysis.reasons.forEach((reason) => {
console.log(reason);
});
return response.riskAnalysis.score;
} else {
console.log("The action attribute in your reCAPTCHA tag does not match the action you are expecting to score");
return null;
}
}
module.exports = { createAssessment }
I call createAssessment from my registration controller.
try {
const test = await createAssessment({
projectID:"my-project-name",
recaptchaKey:process.env.GOOGLE_CAPTCHA_SITE_KEY,
token: recaptchaToken,
recaptchaAction: 'register'
})
console.log(test)
} catch(err){
console.log(`Failed to get assessment: ${err}`)
}
I would expect to see some assessment console logs, but, looking at the logging for the backend container I see ...
Failed to get assessment: SyntaxError: Unexpected token '.'