Search code examples
node.jsamazon-web-servicesnext.jsaws-amplifyrecaptcha-v3

Re-captcha token verification fails in AWS, but not in vercel


Below is my Next.js (backend API) code to verify recaptcha token (created from the client side) and send a mail.

import { NextApiRequest, NextApiResponse } from "next";
import NextCors from 'nextjs-cors';
import { recaptchaAxios } from "../../axios/axiosBackend";
import sendGridMail from '@sendgrid/mail';
sendGridMail.setApiKey(process.env.SENDGRID_API_KEY);

interface FormData {
    contactName: string;
    contactEmail: string;
    contactPhone: string;
    contactSubject: string;
    contactMessage: string;
    token: string;
}

export default async (req: NextApiRequest, res: NextApiResponse) => {

  await NextCors(req, res, {
    // Options
    methods: ['GET','POST'],
    origin: '*',
    optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
 });

  const formData: FormData = req.body;
  console.log("form Data >>>>>>>>>>>>>>",formData)
  const human = await validateHuman(formData.token);

  if (!human) {
    res.status(400);
    return res.json({ success: false, errors: ["You are not authenticated"] });
  }

  const message = {
    to: process.env.SENDGRID_MAIL_RECEIVER, 
    from: process.env.SENDGRID_MAIL_SENDER, // Change to your verified sender
    subject: formData.contactSubject,
    text: `Name: ${formData.contactName}\n 
           Contact: ${formData.contactPhone} \n
           Email: ${formData.contactEmail} \n
           Message: ${formData.contactMessage}`,
    html: `Name: ${formData.contactName}
           Contact: ${formData.contactPhone}
           Email: ${formData.contactEmail}
           Message: ${formData.contactMessage}`,
  }

  try {
    await sendGridMail.send(message);
    res.status(200);
    return res.json({ success: true, errors: [] });
  } catch (error) {
    console.log(error);
    res.status(500);
    return res.json({ success: false, errors: ['Error occured while trying to send your details. Please contact your Administrator.']});
  }
};

async function validateHuman(token: string): Promise<boolean> {
  const secret = process.env.RECAPTCHA_SECRET_KEY;
  const response = await recaptchaAxios.post(`/siteverify?secret=${secret}&response=${token}`,{}, {});
  const success = response.data['success'];
  console.log("server siteverify >>>>>>>>>>>>>",response);
  return success;
}

recaptchaAxios has the baseURL as below

const recaptchaAxios = axios.create({
  baseURL: `https://www.google.com/recaptcha/api`,
});

I have deployed the same code in vercel as well as using AWS Amplify.

In vercel when called to the above mail API, the Recaptcha token is verified and the mail is sent. But unfortunately in AWS it gives the error

{ success: false, errors: ["You are not authenticated"] }

I have added all the environment variables in AWS which I have in vercel and the values are the same. All the domains are added in reCaptch v3 console for the site.

So at this point I am stuck on why in AWS gives the error, but not vercel for the same code base

Is there anything that I am missing in AWS??

Cheers


Solution

  • Issue was in the below code

    const secret = process.env.RECAPTCHA_SECRET_KEY;
    

    Even though the RECAPTCHA_SECRET_KEY was available in the environment variables in AWS, it was not accessible.

    Fix was to introduce this key in next.config.js file

    module.exports = {
      images: {
        domains: [],
      },
      env: {
        RECAPTCHA_SECRET_KEY: process.env.RECAPTCHA_SECRET_KEY,
      },
    };
    

    This solved the problem