Google reCAPTCHA Enterprise with ASP.NET CORE 3.1

Google reCAPTCHA Enterprise with ASP.NET CORE 3.1

在网上搜索 Google reCAPTCHA Enterprise with ASP.NET CORE 3.1 几个小时后,不幸的是,我必须承认我无法找到任何可以在我的应用程序中使用的东西项目。 我已经阅读了 official site 之后的文档,但最后,我仍然坚持要一个干净的实现。

ASP.NET Monsters 中有一个示例,但针对的是 reCAPTCHA V3 而不是 reCAPTCHA 企业版。

这里 Google ReCaptcha v3 server-side validation using ASP.NET Core 5.0 也有一个不错的 post,但在 reCAPTCHA V3 上也是如此。

感谢任何帮助。

所以对我来说,我需要使用 angular 前端通过 dotnet 5 实现 google recapthca。我相信您可以用本机 javascript 替换 angular 前端,但这花了我几个小时的时间进行调查,希望它能对人们有所帮助。

首先我必须启用 reCAPTCHA Enterprise,为此我转到 https://cloud.google.com/recaptcha-enterprise/ 然后单击“转到控制台”按钮。这把我带到了我的 Google 云平台。从这里我需要创建一个密钥,填写选项并保存。此密钥将被称为您的 SITE_KEY.

-- 如果您正在使用 ANGULAR,请阅读此内容,否则请跳过此步骤并自行实施

在客户端我使用了ng-recaptcha,你可以找到它here

为了实现这个组件,我将这个导入添加到我的 app.module.ts

import { RECAPTCHA_V3_SITE_KEY } from 'ng-recaptcha';

并将此提交给提供商部分

      {
          provide: RECAPTCHA_V3_SITE_KEY,
          useValue: SITE_KEY_GOES_HERE
      }

在我的组件上,当按下提交按钮时,我使用了上面库中的 ReCaptchaV3Service。我的代码看起来像这样

this.recaptchaV3Service.execute(YOUR_ACTION_NAME).subscribe((recaptchaResponse) => {
    // now call your api on the server and make sure you pass the recaptchaResponse string to your method
    });

文本 YOUR_ACTION_NAME 是您正在执行的操作的名称。在我的例子中,我传递了 'forgotPassword' 作为这个参数。

-- ANGULAR 部分结束

现在在服务器上,首先我将其包含在我的项目中

<PackageReference Include="Google.Cloud.RecaptchaEnterprise.V1" Version="1.2.0" />

一旦包含在我的服务中,我发现在我的代码中创建服务然后注入就更容易了。我还创建了一个基本选项class,它被注入到我的服务中,如果需要可以注入到其他地方。

RecaptchaOptions.cs

    public class RecaptchaOptions
    {
        public string Type { get; set; }

        public string ProjectId { get; set; }

        public string PrivateKeyId { get; set; }

        public string PrivateKey { get; set; }

        public string ClientEmail { get; set; }

        public string ClientId { get; set; }

        public string SiteKey { get { return YOUR_SITE_KEY; } }

        /// <summary>
        /// 0.1 is worst (probably a bot), 0.9 is best (probably human)
        /// </summary>
        public float ExceptedScore { get { return (float)0.7; } }
    }

其中一些值未使用,但我已添加它们以备将来使用,以备不时之需。

然后我创建了我的服务,看起来像这样(我创建了一个用于注入和测试的接口)

IRecaptchaService.cs

public interface IRecaptchaService
{
    Task<bool> VerifyAsync(string recaptchaResponse, string expectedAction);
}

RecaptchaService.cs

public class RecaptchaService : IRecaptchaService
{
    #region IRecaptchaService

    /// <summary>
    /// Check our recaptcha
    /// </summary>
    /// <param name="recaptchaResponse">The response from the client</param>
    /// <param name="expectedAction">The action that we are expecting</param>
    /// <returns></returns>
    public async Task<bool> VerifyAsync(string recaptchaResponse, string expectedAction)
    {
        // initialize request argument(s)
        var createAssessmentRequest = new CreateAssessmentRequest
        {
            ParentAsProjectName = ProjectName.FromProject(_recaptchaOptions.ProjectId),
            Assessment = new Assessment()
            {
                Event = new Event()
                {
                    SiteKey = _recaptchaOptions.SiteKey,
                    Token = recaptchaResponse
                }
            },
        };

        // client
        var cancellationToken = new CancellationToken();
        var client = RecaptchaEnterpriseServiceClient.Create();

        // Make the request
        try
        {
            var response = await client.CreateAssessmentAsync(createAssessmentRequest, cancellationToken);

            return response.TokenProperties.Valid && response.TokenProperties.Action.Equals(expectedAction) && response.RiskAnalysis?.Score >= _recaptchaOptions.ExceptedScore;
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);

            return false;
        }

    }

    #endregion

    private RecaptchaOptions _recaptchaOptions;

    public RecaptchaService(RecaptchaOptions recaptchaOptions)
    {
        _recaptchaOptions = recaptchaOptions;
    }
}

现在我的 api 端点,我注入此服务并调用它。这是调用 recaptchaService 的示例 API 方法。

public async Task<IActionResult> ForgotPasswordAsync([FromBody] ForgotPasswordModel model)
{
    // check our recaptchaResponse
    var verified = await _recaptchaService.VerifyAsync(model.RecaptchaResponse, "forgotPassword");

    if (!verified)
        throw new ApplicationException("Recaptcha failed, please try again");

    // successful, carry on
}

希望这对大家有帮助,如果有任何问题,请提问,我会编辑并更新我遗漏的内容。