عنوان:

‫روش استفاده از ویژگی Turnstile کلودفلر برای پیاده‌سازی کپچا در برنامه‌های ASP.NET Core


نویسنده: وحید نصیری
تاریخ: ۱۴۰۳/۱۲/۲۹ ۰۹:۴۳
آدرس: www.dntips.ir
مقدمه

در دنیای امروز، امنیت وب‌سایت‌ها از اهمیت بالایی برخوردار است. یکی از چالش‌های مهم در این زمینه، مقابله با ربات‌ها (bots) است که می‌توانند فعالیت‌های مخربی را مانند ارسال درخواست‌های متعدد برای بازنشانی رمز عبور انجام دهند. برای مقابله با این تهدید، از روش‌های مختلفی مانند کپچا (CAPTCHA) استفاده می‌شود. در این مقاله، به بررسی نحوه استفاده از Cloudflare Turnstile به عنوان جایگزینی برای reCAPTCHA گوگل در وب‌سایت‌های ASP.NET Core می‌پردازیم.


تاکنون، از سرویس reCAPTCHA گوگل برای مقابله با ربات‌ها استفاده می‌شد. این سرویس عملکرد خوبی داشت، اما با انتقال آن به Google Cloud، فرصتی برای بررسی جایگزین‌های دیگر فراهم شد. با توجه به استفاده گسترده از خدمات Cloudflare، ویژگی Turnstile آن به عنوان گزینه‌ای مناسب انتخاب شد. یکی از مزایای اصلی Turnstile، سادگی استفاده‌ی از آن برای کاربران است و دیگر نیازی به انتخاب تصاویر چراغ راهنمایی نیست.

برای شروع استفاده از Turnstile در ASP.NET Core، ابتدا باید یک حساب کاربری Cloudflare را ایجاد کنید. سپس، با دنبال کردن مراحل زیر، یک ویجت (widget) Turnstile ایجاد کنید:
  1. در داشبورد Cloudflare، روی Turnstile در منوی سمت چپ کلیک کنید.
  2. روی دکمه Add widget کلیک کنید.
  3. یک نام برای ویجت انتخاب کرده و نام دامنه خود را اضافه کنید.
  4. در Widget Mode، گزینه Managed را انتخاب کرده و سایر گزینه‌ها را به صورت پیش‌فرض رها کنید.
  5. روی دکمه Save کلیک کرده و کلید سایت (site key) و کلید مخفی (secret key) را برای استفاده در مراحل بعدی کپی کنید.

حال به سراغ کدنویسی می‌رویم. در صفحه‌ای که می‌خواهید ویجت Turnstile نمایش داده شود، ابتدا اسکریپت زیر را اضافه کنید:
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=onloadTurnstileCallback" async defer></script>

سپس، در داخل یک عنصر فرم (form)، یک ظرف (container) برای نمایش ویجت اضافه کنید:
<form ...>
  <div id="turnstile-container"></div>
</form>

در مرحله بعد، یک فایل جاوا اسکریپت (JavaScript) ایجاد کرده و کد زیر را در آن قرار دهید:
const captchaSolved = ref(false);

window.onloadTurnstileCallback = function () {
  turnstile.render("#turnstile-container", {
    sitekey: "SITE_KEY",
    callback: function (token) {
        captchaSolved.value = true;
    },
    'expired-callback': function () {
        captchaSolved.value = false;
    }
  });
};
تابع onloadTurnstileCallback توسط اسکریپت Turnstile فراخوانی می‌شود تا ویجت را بارگذاری کند. وقتی کاربر، چالش را با موفقیت حل کند، تابع callback فراخوانی می‌شود. به یاد داشته باشید که SITE_KEY را با کلید سایت Turnstile که در مرحله قبل کپی کردید، جایگزین کنید.

هنگام ارسال فرم، باید توکن (token) تولید شده توسط ویجت Turnstile را نیز ارسال کنید. نحوه پیاده‌سازی درخواست ارسال (submit request) بستگی به فریم‌ورک (framework) مورد استفاده شما دارد. در اینجا یک مثال، با استفاده از data binding در عنصر فرم و یک متد به نام onSubmit آورده شده است:
const onSubmit = handleSubmit(() => {
    const token = turnstile.getResponse();
    if (token === "" || token == undefined || token == null) {
        return;
    }

    captchaSolved.value = false;
    axios
        .post('/myendpoint', Qs.stringify({ captcha: token }))
        .then(response => {
            turnstile.reset("#turnstile-container");
            captchaSolved.value = false;
            
            // Success
        })
        .catch(error => {
            turnstile.reset("#turnstile-container");
            captchaSolved.value = false;

            // Failure
        });
});
کد بالا توکن را از ویجت Turnstile دریافت کرده و به عنوان یک پارامتر (parameter) به بک‌اند (backend) ارسال می‌کند. حال باید متد /myendpoint را در ASP.NET Core پیاده‌سازی کنیم:
public class MyController(Captcha captcha) : ControllerBase
{
    [HttpPost]
    [Route("myendpoint")]
    public async Task<ActionResult> MyEndpoint(string token)
    {
        if (!await captcha.IsValid(token)) return BadRequest();
        
        // Business logic goes here
        
        return Ok();
    }
}
در این مثال، از یک کنترلر MVC استفاده شده است، اما می‌توان این کد را با Minimal API نیز پیاده‌سازی کرد. دقت کنید که endpoint POST توکن تولید شده در کلاینت (client) را به عنوان یک پارامتر به نام token دریافت می‌کند و این توکن برای اعتبارسنجی (validation) به یک کلاس به نام Captcha ارسال می‌شود.

برای پیاده‌سازی اعتبارسنجی توکن، کلاس Captcha را به عنوان یک کلاینت HTTP ساده پیاده‌سازی می‌کنیم. اگرچه پکیج‌های NuGet متعددی برای این کار وجود دارند، اما پیاده‌سازی دستی آن بسیار ساده است:
public class Captcha(HttpClient captchaClient)
{
    public async Task<bool> IsValid(string token)
    {
        try
        {
            var formData = new Dictionary<string, string>
            {
                { "secret", "SITE_SECRET" },
                { "response", token }
            };

            var content = new FormUrlEncodedContent(formData);
            var postTask = await captchaClient.PostAsync("/turnstile/v0/siteverify", content);

            var result = await postTask.Content.ReadAsStringAsync();
            var resultObject = JsonSerializer.Deserialize<JsonElement>(result);
            return resultObject.GetProperty("success").GetBoolean();
        }
        catch
        {
            return false;
        }
    }
}
کلاس Captcha اعتبارسنجی توکن را با استفاده از HttpClient ارائه شده در سازنده (constructor) پیاده‌سازی می‌کند. متد IsValid یک درخواست HTTP POST به endpoint /turnstile/v0/siteverify با کلید مخفی Turnstile و توکن تولید شده ارسال می‌کند. API Cloudflare یک مقدار بولی (boolean) را برمی‌گرداند که نشان‌دهنده معتبر بودن یا نبودن توکن است. به یاد داشته باشید که SITE_SECRET را با کلید مخفی Turnstile که در مرحله قبل کپی کردید، جایگزین کنید.

تنها بخش باقی‌مانده، تنظیم کلاس Captcha برای تزریق وابستگی (dependency injection) در Program.cs است:
builder.Services.AddHttpClient<Captcha>(x =>
{
    x.BaseAddress = new Uri("https://challenges.cloudflare.com");
});
این کد کلاس Captcha را با یک HttpClient ارائه شده اضافه می‌کند که با API Cloudflare ارتباط برقرار می‌کند.

نتیجه‌گیری
با انجام این مراحل، Turnstile در ASP.NET Core پیاده‌سازی می‌شود و مقابله با ربات‌ها برای وب‌سایت شما دشوارتر می‌شود، در حالی که تجربه کاربری برای کاربران واقعی بهبود می‌یابد. اگر از خدمات Cloudflare استفاده می‌کنید، Turnstile یک گزینه عالی برای پیاده‌سازی کپچا در ASP.NET Core است.


مشاهده مطلب اصلی