2

我为我的前端创建了一个 ReCaptcha Enterprise 项目,并试图在 AWS Lambda 中验证评估。

ReCaptcha 项目如下所示:ReCaptcha 设置

前端代码是一个反应应用程序,但我只是使用文档之后的脚本。这一切似乎都奏效了。我可以解决验证码并得到答案。

const [captchaAnswer, setCaptchaAnswer] = useState<string | null>(null);

useEffect(() => {
    const script = document.createElement('script');

    script.src = "https://www.google.com/recaptcha/enterprise.js";
    script.async = true;
    script.defer = true;

    document.body.appendChild(script);
        
     return () => {
        document.body.removeChild(script);
    }
}, []);


window.reCaptchaCallback = function (response: string) {
    setCaptchaAnswer(response);
};

const submit = () => {
    //Submits the answer to my lambda
}

return (
    <div className="g-recaptcha" data-sitekey="<SITEKEY>" data-callback="reCaptchaCallback" />
);

所以接下来是 lambda,它被称为 Cognito 的触发器。

const axios = require("axios");

const config = {
  PROJECT_ID: "<PROJECTID>",
  API_KEY: "<APIKEY>", //actually gotten from secret manager
  SITE_KEY:"<SITEKEY>"
};

exports.handler = async (event) => {
  console.log(event);
  
  if (event.triggerSource === "PreSignUp_AdminCreateUser") {
    return event;
  }

  if (!event.request.validationData) {
    throw new Error('Missing validation data');
  }
  
  try {
    const verifyResponse = await axios({
      method: 'post',
      url: `https://recaptchaenterprise.googleapis.com/v1beta1/projects/${config.PROJECT_ID}/assessments?key=${config.API_KEY}`,
      body: {
        event: {
          token: event.request.validationData.token, //I have confirmed this is correctly passed from front end to here
          siteKey: config.SITE_KEY
          expectedAction: "" //Tried it with and without this. Documentation say it isn't being used
        }
      },
      headers: { "Content-Type": "application/x-www-form-urlencoded" }
    });

    console.log(JSON.stringify(verifyResponse.data));
    
    if (verifyResponse.data.score >= 0) {
      event.response.autoConfirmUser = true;
      return event;
    } else {
      throw new Error('Recaptcha verification failed');
    }
  } catch (error) {
    console.error(error);
    throw new Error("Recaptcha verification failed. Please retry");

  }
};

这是我总是得到的回应。

{
    "name": "projects/<PROJECT>/assessments/924d7fc3f0000000",
    "score": 0,
    "reasons": []
}

然而,recaptcha 仪表板显示所有的评估都 >= 0.8 我不知道我做错了什么。感谢您的任何帮助。

4

3 回答 3

2

根据我的经验,tokenProperties响应中的缺失意味着 googleapis.com 未能读取您的 POST 数据。

对于您的情况,首先预期的内容类型应该是 json:

    "Content-Type": "application/json; charset=utf-8"

如果更改上述内容不能解决问题,请尝试将 post 数据从 object/dict/json 更改为字符串

提示:一般来说,当我们在代码中无法获得预期的响应时,我们可以尝试在 curl 或 jmeter 等直接工具中试验目标请求以找出问题所在,然后将解决方案复制回我们的代码中。

于 2021-07-16T04:57:55.090 回答
1

这是对我有用的卷曲,可能对你有帮助。在您的代码中,查看正文并发送一个“评估”对象,其中包括“事件”对象。

curl -H 'Content-Type: application/x-www-form-urlencoded' -X POST https://recaptchaenterprise.googleapis.com/v1beta1/projects/${here-is-your-id-project}/assessments?key=${here-is-your-secret-key-defined-on-credentials-api-section} -d 'assessment.event.token=${response-token-coming-from-grecaptcha.enterprise.execute-method-on-web-site}' -d 'assessment.event.site_key=${here-is-your-public-key-defined-on-recaptcha-service-section}'

这是回应:

{
  "name": "projects/xxxx/assessments/xxxxx",
  "event": {
    "token": "${response-token-coming-from-grecaptcha.enterprise.execute-method-on-web-site}",
    "siteKey": "${here-is-your-public-key-defined-on-recaptcha-service-section}",
    "userAgent": "",
    "userIpAddress": "",
    "expectedAction": "",
    "hashedAccountId": ""
  },
  "score": 0.9,
  "tokenProperties": {
    "valid": true,
    "invalidReason": "INVALID_REASON_UNSPECIFIED",
    "hostname": "your-host-goes-here",
    "action": "login",
    "createTime": "2022-02-03T19:08:01.612Z"
  },
  "reasons": []
}

我的 GCP 配置:

就这样

于 2022-02-04T10:00:52.360 回答
0

我有同样的问题。如果有人现在拥有它,这就是答案:将 axios 调用更改为使用.post

const { data } = await axios.post(
`https://recaptchaenterprise.googleapis.com/v1beta1/projects/${CAPTCHA_PROJECT_ID}/assessments?key=${CAPTCHA_API_KEY}`,
{
  event: {
    token: tokenValue,
    siteKey: CAPTCHA_SITE_KEY,
    expectedAction: "YOUR_ACTION",
  },
},
{
  headers: {
    "Content-Type": "application/json; charset=utf-8",
  },
});
于 2022-02-16T10:17:51.107 回答