LoginSignup
0
2

More than 3 years have passed since last update.

初心者おばちゃんの簡単ASP.NET Razor Pages / ReCAPTCHAセッティング

Last updated at Posted at 2020-07-26

reCAPTCHAとは

ウェブサイトの制限エリアへのアクセスを試みるボットからサイトを防御するためCAPTCHAを利用するのと同時に、そのCAPTCHAに対する返答を紙の本のデジタル化に活かすシステムである。(ウィキペディア参照)

とあります。
意外と情報が少なく、初心者にはハードルが高かったので、この度わかる範囲でシェアさせていただきました。つたない説明やコーディングで申し訳ございませんが、お付き合いください。

設定方法

*横スクロールの関係で見やすくするためにコードを切ってしまってますが、はぶいているラインはありません。

1.使用言語と準備

  • ASP.NET Core
  • Razor Pages
  • Google reCAPTCHA

2.Google reCAPTCHAの設定

こちらからadmin console(設定)へ
https://www.google.com/recaptcha/intro/v3.html

  • Label ターゲットサイトの名前をReCAPCTA用につけてやります。
  • reCAPTCHA type シークレット・キーが生成されています。

    • SiteKey : "xxxxxxxxxxxxxxxxxxxxxxVG999999999999999999"
    • SecretKey : "9LQQQQQQQQQQQQQQQQQQzzzzzzzzzzzzzzzzzzzz"
  • Domains

    • 本番用 - yourdomain.com
    • ローカル用 - localhost
  • Owners ご自身のメールアドレス

  • Security Preference 必要に合わせて

  • Verify the origin of reCAPTHA solutions reCAPTCHA
    ソリューションの起源を確認する
    無効にした場合、ソリューションを検証するときにサーバーのホスト名を確認する必要があります。

  • Send alerts to owners Send alerts to owners
    Receive alerts if Google detects problems with your site, such as a misconfiguration or an increase in suspicious traffic.
    所有者にアラートを送信所有者にアラートを送信
    Googleが設定の誤りや疑わしいトラフィックの増加など、サイトの問題を検出した場合にアラートを受信します。

3.キーの保存先

appsettings.json

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "reCAPTCHA": {
        "SiteKey": "xxxxxxxxxxxxxxxxxxxxxxVG999999999999999999",
        "SecretKey": "9LQQQQQQQQQQQQQQQQQQzzzzzzzzzzzzzzzzzzzz"
    }
   }
}

4.フロントエンドへの設定(ターゲットページ) 

Index.cshtml

@page

@using Microsoft.Extensions.Configuration
@model xxxx.zzzzz.testIndex
@inject IConfiguration configuration
<div class="container">
    <main role="main" class="pb-3">
        <h1>Log In</h1>
        <div class="row">
            <div class="span12 p-3" style="min-width:100%">
                <div class="row">
                    <div class="font-weight-bold span6 col-sm-6 p-3">
                        <div>
                            <p class="text-danger">@Model.Message</p>
                        </div>
                        <form method="post">
                            <div class="form-group">
                                <label asp-for="UserName" class="control-label">User Name</label>
                                <div class="col-md-10">
                                    <input asp-for="UserName" />
                                </div>
                            </div>
                            <div class="form-group">
                                <label asp-for="Password" class="control-label">Password</label>
                                <div class="col-md-10">
                                    <input asp-for="Password" />
                                </div>
                            </div>
                            <div class="form-group">
                                <label asp-for="ID" class="control-label">ID</label>
                                <div class="col-md-10">
                                    <input asp-for="ID" />
                                </div>
                            </div>
                            <div class="g-recaptcha" data-sitekey="@configuration["reCAPTCHA:SiteKey"]"></div>
                            <br />
                            <div class="form-group">
                                <button class="btn btn-primary">Log in</button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
        @section Scripts {
            @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
            <script src="https://www.google.com/recaptcha/api.js" async defer></script>
        }
    </main>

5.バックエンドへの設定1(モデル) 

reCAPTCHA.cs

namespace XXX.Models
{
    public class reCAPTCHA
    {
        public string SiteKey { get; set; }
        public string SecretKey { get; set; }
    }
}

6.バックエンドへの設定2(ターゲットページ)

Index.cshtml.cs

using System.ComponentModel.DataAnnotations;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Web;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace xxx.zzzz.vvvv
{
    public class testIndexModel : PageModel
    {
        private readonly IConfiguration configuration;

        [BindProperty]
        public string UserName { get; set; }
        [BindProperty]
        public int ID { get; set; }

        [BindProperty, DataType(DataType.Password)]
        public string Password { get; set; }

        public string Message { get; set; }

        public IHttpClientFactory ClientFactory { get; }

        public ILogger Logger { get; }
        public object HttpHelper { get; private set; }
        public testIndexModel(ILogger<testIndexModel> logger, 
            IConfiguration configuration, 
            IHttpClientFactory clientFactory)
        {
            Logger = logger;
            this.configuration = configuration;
            ClientFactory = clientFactory;
        }

        public void OnGet(string message)
        {
            Message = message;
        }
        public async Task<IActionResult> OnPostAsync(xxx.Models.testuser testuser)//** ユーザー認証のモデル **//
        {
            string recaptchaResponse = this.Request.Form["g-recaptcha-response"];
            var client = ClientFactory.CreateClient();
            var reCAPTCHA = configuration.GetSection("reCAPTCHA").Get<xxx.Models.reCAPTCHA>();

            try
            {
                var parameters = new Dictionary<string, string>
                {
                    {"secret", reCAPTCHA.SecretKey},
                    {"response", recaptchaResponse},
                    {"remoteip", this.HttpContext.Connection.RemoteIpAddress.ToString()}
                };
                HttpResponseMessage response = await client.PostAsync("https://www.google.com/recaptcha/api/siteverify", new FormUrlEncodedContent(parameters));
                response.EnsureSuccessStatusCode();

                string apiResponse = await response.Content.ReadAsStringAsync();
                dynamic apiJson = JObject.Parse(apiResponse);
                if (apiJson.success != true)
                {
                    this.ModelState.AddModelError(string.Empty, "ログインエラーが発生しました ");
                }
                if (ModelState.IsValid)
                //** ユーザー認証を行います **//
                {
                    if (testuser.IsValid(testuser.UserName, testuser.Password, ((int)testuser.ID).ToString()))
                    {
                        Response.Redirect("/xxx/zzzz/testIndex?id=" + HttpUtility.UrlEncode(((int)testuser.ID).ToString()));
                    }
                }
                Message = "ログインエラーが発生しました";
            }
            catch (HttpRequestException ex)
            {
                this.Logger.LogError(ex, "Unexpected error calling reCAPTCHA api.");
            }
            return Page();
        }
    }
}

動画集

初心者おばちゃんの簡単ASP.NET Razor PagesでRESTFul/Ajax使ってみよう
実際に使ってるOboeroシステムの動画

Oboero メモリーシステム

Oboero メモリーシステム

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2