I have the following codes that verify Google reCAPTCHA v3 in my Firebase Function that caused the CORS issue:
const functions = require('firebase-functions');
const nodemailer = require("nodemailer");
const express = require("express");
const cors = require("cors");
const request = require('request');
const serverApi = express();
api.use(cors({ origin: true }));
function verifyCaptcha(token, returnData) {
// Put your secret key here.
var secretKey = functions.config().recaptcha.secretkey;
var verificationUrl = "https://www.google.com/recaptcha/api/siteverify?secret=" + secretKey + "&response=" + token;
// Note here: External network call to google.com
request(verificationUrl, function (error, response, body) {
body = JSON.parse(body);
// Success will be true or false depending upon captcha validation.
if (!body.success) {
body['status'] = false;
body['errSource'] = "recaptcha";
body['message'] = "Failed to pass captcha verification.";
} else {
body['status'] = true;
body['message'] = "Successfully passed captcha verification!";
};
console.log(`Google returns: ${JSON.stringify(body)}`);
returnData(body);
});
};
api.post("/api/service-name", (req, res) => {
if (!req.body['g-recaptcha-response']) {
return res.send({ "status": false, "errSource": "recaptcha", "message": "Client-side reCAPTCHA token not found." });
};
const recaptchaToken = req.body['g-recaptcha-response'];
verifyCaptcha(recaptchaToken, function (result) {
if (result.status == false) {
return res.send(result);
};
// My business logics here.
});
});
exports.api = functions.https.onRequest(api);
I noticed that after removing the reCAPTCHA v3 verification request in within my Firebase Function, no more CORS issue for my localhost to call "/api/service-name"
using $.ajax()
. This is because the following Firebase Function log reminded me of the "External network is not accessible":
Billing account not configured. External network is not accessible and quotas are severely limited.
Configure billing account to remove these restrictions
My question is: Is there a way to get my server-side reCAPTCHA verification to work without causing this CORS issue, which could be prevented by "Billing account not configured"? Thanks!
UPDATE:
After catching the request()
error that does the verification, I get the following error:
{errno: "EAI_AGAIN", code: "EAI_AGAIN", syscall: "getaddrinfo", hostname: "www.google.com", host: "www.google.com", …}
Also, after handling this error, no more CORS issue, but reCAPTCHA still cannot be verified. Any idea what causes this? Thanks again!
It's now confirmed that the above issue has been resolved after Enable Billing at the Google Cloud Console. It is NOT actually the CORS issue between the localhost and Firebase Functions/Hosting (although the Chrome browser returned as CORS related error message), it's actually the HTTP Request from the Firebase Function to the Google reCAPTCHA api during token verification process. Due to billing account not linked to the Firebase Project where the function sits in, any requests from any Firebase Functions to any External Network Resources, including Google reCAPTCHA, will be rejected with the following errors:
HTTP Request Error:
{errno: "EAI_AGAIN", code: "EAI_AGAIN", syscall: "getaddrinfo", hostname: "www.google.com", host: "www.google.com", …}
After enabling billing at GCP and linking the billing account to the specific Firebase Project, the request to Google reCAPTCHA verification will be successful (if the token is valid) without the above error. However, your FREE Spark Tier Firebase account will be AUTOMATICALLY UPGRADED to Blaze Plan -- Pay as you go.