Re-captcha token 验证在 AWS 中失败,但在 vercel 中没有

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

下面是我的 Next.js(后端 API)代码,用于验证 recaptcha 令牌(从客户端创建)并发送邮件。

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 的 baseURL 如下

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

我已经在 Vercel 中部署了相同的代码并使用了 AWS Amplify。

在 vercel 中调用上述邮件时 API,验证 Recaptcha 令牌并发送邮件。 但不幸的是,在 AWS 中它给出了错误

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

我在AWS中添加了我在vercel中的所有环境变量,并且值是相同的。 所有域都添加到站点的 reCaptch v3 控制台中。

所以在这一点上我坚持为什么在 AWS 中给出错误,但对于相同的代码库 Vercel 却没有给出错误

我在 AWS 中遗漏了什么吗??

干杯

我的第一个指针是 console.log 脚本加载时的环境变量,也是每次触发 recaptcha 验证时。这样您就可以确保 ENV 变量都已正确加载。你会惊讶于有一个小的区分大小写的错字,让你没有一个重要的环境变量。

否则,我会检查是否需要允许 AWS amplify 上的传出流量(防火墙规则),但这不太常见,因为 AWS Amplify 生成了一个 public 站点。

问题出在下面的代码中

const secret = process.env.RECAPTCHA_SECRET_KEY;

尽管 RECAPTCHA_SECRET_KEY 在 AWS 的环境变量中可用,但无法访问。

修复是在 next.config.js 文件中引入这个密钥

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

这解决了问题