مفهوم کپچا (CAPTCHA) و نحوه‌ی پیاده‌سازی آن در سایت‌های مختلف

PHP Captcha

13 اسفند 1399
captcha

اگر در عمرتان از اینترنت استفاده کرده باشید حتما کدهای کپچا (CAPTCHA) را دیده اید. این کدها فرم های مختلفی دارند اما معمول ترین آن ها بدین شکل است که تصویری با رزولوشن بسیار پایین و به هم ریخته به شما داده می شود و وظیفه شما فهمیدن و نوشتن متن آن درون فیلد مربوطه است. همچنین در برخی اوقات مجموعه ای از تصاویر بی کیفیت به شما داده شده و از شما خواسته می شود که اشیاء خاصی را در این تصاویر پیدا کنید.

هدف از این کار به طول کل «محافظت» از وب سایت شماست. این محافظت شکل های مختلفی دارد که توضیح خواهم داد اما کلیت بحث این است که انسان ها بتوانند این تصاویر بی کیفیت و کج و کوله را بخوانند در حالی که ربات ها قادر به انجام چنین کاری نباشند. با این کار ربات ها نمی توانند وارد وب سایت شما بشوند و وب سایت محافظت خواهد شد. احتمالا بپرسید مگر ربات ها چه کار می کنند؟

ربات ها با اهداف مختلفی به سمت وب سایت شما فرستاده می شوند. یکی از ساده ترین حملات آن ها، حملات Brute force است که طی آن یک ربات به طور مکرر شروع به وارد کردن اطلاعات مختلف درون فرم login شما می کند تا بالاخره یکی از تلاش هایش نتیجه دهد. این کار شبیه به وقتی است که سعی می کنیم رمز یک کیف سامسونت را با حدس زدن پیدا کنیم؛ آنقدر عددهای مختلف را وارد می کنیم تا بالاخره به عدد صحیح برسیم. این ربات ها نیز با پیروی از همین الگو سعی در حدس زدن رمز شما (مثلا ادمین سایت) می کنند.

یکی دیگر از حملات رایج ربات ها Cross-Site Scripting یا XSS است که طی آن ربات ها یا خود هکر کدهای مخربی را وارد فرم های شما می کند (مثلا فرم لاگین یا قسمت کامنت ها یا هر قسمتی که ورودی از کاربر گرفته می شود). اگر در هنگام کدنویسی سمت سرور، استانداردهای امنیتی را رعایت نکرده باشید این کدهای مخرب که در فرم شما قرار گرفته و ارسال شده اند، در سرور دریافت شده و به جای ذخیره سازی یا پردازش سریعا اجرا می شوند. هکرها سعی دارند با این کار یا به سایت شما ضربه بزنند (حذف اطلاعات پایگاه داده و ...) و یا اینکه اطلاعات شما یا کاربران شما را به سرقت ببرند.

از حملات رایج دیگر ربات ها حملات spamming است که طی آن صدها ربات به وب سایت شما ارسال می شوند تا در قسمت کامنت های سایت شروع به تبلیغ لینک ها و مطالب مورد نظرشان کنند. این ربات ها مکررا در سایت شما و زیر مطالب مختلف کامنت می گذارند و برای خودشان تبلیغ می کنند که تبعات بدی را دارد. اول از همه این کار به سئوی سایت شما ضربه می زند چرا که این لینک ها معمولا یا لینک های بی کیفیتی هستند و یا به وب سایت های غیراخلاقی منتهی می شوند و گوگل تکرار چنین کامنت هایی در سراسر سایت شما را تشخیص می دهد. همچنین مسئله بعد ظاهر وب سایت شما است که به شدت به هم می ریزد و کاربرانی که تازه به وب سایت شما وارد شوند قطعا وب سایت شما را ترک می کنند.

بنابراین به زبان ساده می توان گفت در هر قسمتی از سایت شما که داده هایی از سمت کاربر دریافت شود، ربات ها می توانند خراب کاری انجام بدهند بنابراین در تمام این قسمت ها نیاز به کپچا داریم.

reCAPTCHA ارائه شده توسط گوگل

با اینکه کپچاها از نظر امنیتی به وب سایت ما کمک می کنند اما از نظر UX تاثیر بدی روی سایت ما می گذارند چرا که در عمل سدی مقابل کاربر هستند که تعامل کاربر با سایت ما را کُند می کنند. کاربر ما که قبلا می توانست به راحتی کامنت خود را ثبت کند حالا باید یک تست جداگانه را کامل کند تا بتواند به مرحله کامنت گذاری برسد. بسیاری از وبمستران برای حل این مشکل از کپچاهای ساده تر و عددی استفاده می کنند (مثلا نتیجه 2 به علاوه 6 چیست؟) اما به علت سادگی زیاد، برخی از ربات ها قادر هستند آن ها را حل کنند. همچنین این کپچاها هنوز مشکل اصلی ما را حل نکرده اند؛ یعنی هنوز هم به کاربران خود یک تست اضافه دادیم که باید برای حل آن وقت بگذارند (کاهش UX). از طرفی کاربرانی که دچار مشکلات جسمی مانند نابینایی یا ضعف شدید بینایی یا بیماری های ادراکی و شناختی مانند دیلکسیا باشند، نمی توانند به سادگی کپچاها را خوانده و تشخیص دهند.

گوگل در سال 2014 وارد عمل شد و برای حل این مشکل یک کپچای خاص به نام No CAPTCHA reCAPTCHA را ارائه کرد. این کپچا از کاربر می خواهد که تیک گزینه ای به نام I’m not a robot را بزند. این فرآیند (کلیک کردن ساده) بسیار راحت تر از حل مسئله و خواندن متن های عجیب و غریب است و به UX ضربه ای نمی زند. در واقع گوگل الگوریتم خاصی برای این نوع از کپچا طراحی کرده است که در آن ترافیک ورودی از سمت کاربر یا ربات (هر کسی که روی I’m not a robot کلیک کند) را بررسی و تحلیل می کند. اکثر کاربران عادی که به ابزارهای رفع تحریم مانند vpn یا proxy متصل نباشند، به راحتی و با یک کلیک ساده تایید می شوند و نیازی نیست که تست خاصی را حل کنند.

نمونه ای از کپچای گوگل
نمونه ای از کپچای گوگل

اما از آنجا که ربات ها معمولا به صورت خودکار مدیریت می شوند، دارای ترافیک ورودی خاصی هستند که در اکثر مواقع شناسایی آن ها ساده است. دلیل حرف من مبنی از استفاده از vpn و proxy و سرویس های مشابه نیز همین است؛ استفاده از این نوع سرویس ها ترافیک شما را رمزنگاری می کند و این ترافیک رمزنگاری شده شباهت زیادی با ترافیک ربات ها دارد. برای تست این موضوع می توانید یک پنجره incognito را در مرورگر کروم یا فایرفاکس باز کرده و سپس با استفاده از سرویس های vpn یا proxy به وب سایت google.com بروید. به احتمال زیاد گوگل از شما می خواهد که یک تست کپچا را انجام بدهید.

بنابراین کاربران عادی نیازی به انجام تست ندارند و کاربران مشکوک یا ربات ها حتما باید تست را تکمیل کنند. البته گوگل این سرویس را بسیار پیشرفته تر کرده است و از سال 2018 چیزی به نام invisible CAPTCHA یا «کپچای نامرئی» را ارائه می دهد که با بارگذاری آن در وب سایت هیچ چیزی تغییر نمی کند (حتی گزینه ای هم وجود ندارد که کاربر روی آن کلیک کند) و فقط در صورتی کپچا ظاهر می شود که ترافیک کاربر مشکوک باشد.

در ادامه، در رابطه با نحوه پیاده سازی این کپچاها در وب سایت های مختلف با شما صحبت خواهیم کرد.

پیاده سازی کدهای CAPTCHA: نسخه دوم - checkbox

تا به اینجا در رابطه با مفهوم و دلایل استفاده از کپچاها صحبت کردیم و سپس با سرویس های جدید گوگل برای پیاده سازی کپچا آشنا شدیم اما در این بخش می خواهیم این کار را به صورت عملی انجام بدهیم. من این آموزش را برای دو نوع از وب سایت های وردپرسی و غیر وردپرسی می نویسم تا همه شما بتوانید از آن استفاده کنید.

پیاده سازی کپچا در وب سایت های وردپرسی

برای پیاده سازی کپچا در این نوع وب سایت ها بهترین راه حل استفاده از پلاگین های کپچا است اما برای انتخاب نوع پلاگین باید به دو نکته توجه کنید:

  • همانطور که در قسمت قبل توضیح دادیم، کپچای گوگل بسیار بهتر از انواع دیگر کپچا است بنابراین باید تمرکز خود را روی پلاگین هایی بگذارید که حتما از سرویس Google reCAPTCHA استفاده کنند.
  • از آنجا که معمولا در سایت های ما چندین فرم و قسمت های مختلفی برای دریافت داده های کاربران وجود دارد، پلاگین انتخابی ما باید بتواند کپچا را به چندین قسمت اضافه کند. بسیاری از پلاگین های رایگان چنین قابلیتی را ندارند و فقط می توانند کپچا را به یک قسمت اضافه کنند.

با حفظ این دو نکته چند پلاگین مشهور در این زمینه را به شما معرفی می کنم.

پلاگین های مشهور CAPTCHA

پلاگین Google Captcha (reCAPTCHA) by BestWebSoft بدون شک محبوب ترین پلاگین کپچای گوگل است که در حال حاضر 200 هزار نصب فعال دارد. این پلاگین می تواند از نسخه های دوم و سوم (v2 و v3) کپچای گوگل (Google reCAPTCHA) استفاده کند. این پلاگین قابلیت اضافه کردن کپچا به فرم های ورود و ثبت نام، فرم های بازیابی رمز عبور، فرم های تماس با ما، قسمت کامنت ها و غیره را دارد بنابراین از این نظر نیز خیالمان راحت است.

پلاگین بعدی Advanced noCaptcha & Invisible Captcha است که تمامی قابلیت های ذکر شده برای پلاگین قبلی را نیز دارد. همچنین یکی دیگر از قابلیت های این پلاگین multisite compatibility است که یعنی می توانید از آن روی چندین سایت استفاده کنید. این پلاگین با سرویس های دیگری مانند bbPress و BuddyPress نیز یکپارچه می شود و مشکلی با آن ها ندارد. همچنین می توانید در صورت نیاز به یک فرم چندین کپچا اضافه کنید.

در نهایت پلاگین محبوب بعدی  Login No CAPTCHA reCAPTCHAاست که از سیستم Google reCAPTCHA استفاده می کند اما نسبت به دو مورد قبل محدود تر است چرا که توانایی اضافه کردن کپچا به قسمت کامنت ها و فرم های تماس با ما را ندارد. تا اینجای کار باید پلاگین خود را نصب کرده باشید. از این قسمت به بعد را باید در قسمت «پیاده سازی reCAPTCHA در سایت های غیر وردپرسی» مطالعه کنید تا بتوانید حساب کپچای خود را در گوگل فعال کنید. به عنوان توجه نکنید، ادامه کار شما مانند بقیه سایت ها است و باید ادامه همین مقاله را دنبال کنید.

پیاده سازی Google reCAPTCHA در سایت های غیر وردپرسی

برای استفاده از reCAPTCHA در سایت های عادی (و همچنین وردپرسی) باید ابتدا به صفحه مدیریتی erCAPTCHA در گوگل بروید و یک کپچای جدید برای خود بسازید. برای این کار باید فرم زیر را تکمیل کنید:

فرم درخواست کپچا از گوگل
فرم درخواست کپچا از گوگل

همانطور که می بینید در این فرم باید بین نسخه دوم و سوم reCAPTCHA انتخاب کنید. همچنین نوع کپچای شما نیز در این قسمت انتخاب می شود. من به شما پیشنهاد می کنم که از همان نسخه دوم (v2) استفاده کنید چرا که نسخه سوم مخصوص وب سایت های خاص است و مشکلاتی نیز دارد. مثلا اسکریپت های نسخه سوم باید در تمام صفحات وب سایت شما بارگذاری شده و به همراه لینک «حریم خصوصی» یا privacy باشند. همچنین علاوه بر رفتار کاربر (کلیک ها و حرکات موس) تمامی محتوای فرم نیز به گوگل آپلود می شود بنابراین سعی کنید از همان نسخه دوم استفاده نمایید. من فعلا روی حالت checkbox تمرکز می کنم و در انتهای مقاله گزینه invisible را نیز توضیح خواهم داد.

در نهایت دامنه هایی که کپچا باید در آن کار کند را نیز مشخص می کنیم. من localhost را نیز قرار داده ام تا بتوانم آن را هنگام توسعه روی سیستم خودم هم امتحان کنم. معمولا می توانید از آن روی آدرس http://localhost:8080 استفاده کنید. زمانی که روی submit کلیک کنید یک Site Key و یک Secret Key دریافت خواهید کرد. اگر از پلاگین های وردپرس استفاده می کنید، این دو مقدار را در تنظیمات پلاگین خود وارد کنید.

پس از ثبت نام site key و secret key به شما داده خواهد شد
پس از ثبت نام site key و secret key به شما داده خواهد شد

حالا تگ زیر را درون تگ <head> از فایل HTML خود قرار دهید (هر جایی که باید کپچا داشته باشید):

<script src='https://www.google.com/recaptcha/api.js' async>

البته به جای async می توانید از Defer نیز استفاده نمایید و به شما بستگی دارد. حتی می توانید از هیچ کدام استفاده نکنید:

    <script src='https://www.google.com/recaptcha/api.js'></script>

البته پیشنهاد می شود برای سرعت بخشیدن به بارگذاری صفحات از async یا defer استفاده نمایید.

حالا باید در فرم خود قسمتی داشته باشید که کلاس g-recaptcha را داشته باشد. معمولا از یک تگ div برای این کار استفاده می شود. همچنین روی همین تگ باید یک attribute از نوع data به نام data-sitekey وجود داشته باشد. بنابراین تگ ما به شکل زیر خواهد بود:

<div class="g-recaptcha" data-sitekey="your_site_key">

در تگ بالا به جای your_site_key باید همان secret دریافت شده از مراحل قبل را قرار بدهید (تصویر قبلی). مثلا یک فرم عادی به شکل زیر خواهد بود:

<form class="contact__form" method="post" action="mail.php">

    <!-- form message -->
    <div class="row">
        <div class="col-12">
            <div class="contact__msg" style="display: none">
                <p>Your message was sent successfully.</p>
            </div>
        </div>
    </div>
    <!-- end message -->

    <!-- form element -->
    <div class="row">
        <div class="col-md-6 form-group">
            <input name="name" type="text" class="form-control" placeholder="Name" required>
        </div>
        <div class="col-md-6 form-group">
            <input name="email" type="email" class="form-control" placeholder="Email" required>
        </div>
        <div class="col-md-6 form-group">
            <input name="phone" type="text" class="form-control" placeholder="Phone" required>
        </div>
        <div class="col-md-6 form-group">
            <input name="subject" type="text" class="form-control" placeholder="Subject" required>
        </div>
        <div class="col-12 form-group">
            <textarea name="message" class="form-control" rows="3" placeholder="Message" required></textarea>
        </div>
        <div class="col-12 form-group">
            <div class="g-recaptcha" data-sitekey="___enter_site_key___"></div>
        </div>
        <div class="col-12">
            <input name="submit" type="submit" class="btn btn-success" value="Send Message">
        </div>
    </div>
    <!-- end form element -->
</form>

یعنی فرم به همان شکلی است که شما می خواهید (حتما نباید شبیه فرم بالا باشد) فقط باید به آن یک تگ (معمولا div) اضافه کنید که کلاس و attribute ذکر شده را داشته باشد. توجه کنید که این یک فرم نمونه است و گرنه فرم های شما می توانند بسیار ساده تر باشند، تنها قسمت مهم، این کد است:

<div class="g-recaptcha" data-sitekey="___enter_site_key___"></div>

حالا باید پاسخ کپچا را در سمت سرور بررسی کنیم بنابراین من از یک کد ساده PHP استفاده می کنم:

<?php
 
  if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response']))
  {
        $secret = 'your_actual_secret_key';
        $verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response']);
        $responseData = json_decode($verifyResponse);
        if($responseData->success)
        {
            $succMsg = 'اطلاعات شما با موفقیت ذخیره شد.';
        }
        else
        {
            $errMsg = 'شما نتوانستید کدهای کپچا را کامل کنید. لطفا دوباره تلاش نمایید.';
        }
   }

همانطور که می بینید ابتدا چک می کنیم که 'g-recaptcha-response' خالی نباشد (کاربر کپچا را انجام داده باشد، چه درست و چه غلط). سپس باید secret key خود را به متغیر secret بدهید (فعلا عبارت عادی 'your_actual_secret_key' در آن قرار دارد که اشتباه است). سپس با استفاده از تابع file_get_contents می توانیم دستور خود را به آدرس زیر ارسال کنیم:

https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response']

پاسخ دریافتی از سرور گوگل به صورت JSON است بنابراین باید آن را با json_decode به حالت عادی برگردانیم. در نهایت اگر عملیات موفقیت آمیز بوده باشد خصوصیت success درون پیام برگردانده شده از سمت گوگل خواهد بود که من برای این حالت فقط یک متغیر ساده تعریف کرده ام (شما باید کار مورد نظر خود را انجام دهید). در غیر این صورت کاربر کپچا را به درستی انجام نداده است. به همین سادگی یک کپچا از نوع checkbox داریم.

در ادامه، در مورد حالت invisible (نامرئی) و نسخه سوم گوگل کپچا صحبت خواهیم کرد.

پیاده سازی Google reCAPTCHA از نوع Invisible

در ابتدا و مثل حالت قبل باید یک حساب ساخته و secret key و site key خود را از گوگل دریافت کنید. بدون این دو مورد نمی شود کاری انجام داد. پس از اینکه حساب خود را ساختید به این قسمت برگشته و ادامه مقاله را مطالعه کنید.

نوع invisible کپچای گوگل نوعی از کپچا است که توسط جاوا اسکریپت و به صورت خودکار، عملیات زدن تیک را انجام می دهد. چرا؟ به دلیل اینکه کپچا اصلا به کاربر نمایش داده نشود و تیک آن به صورت خودکار زده شود. در صورتی که ترافیک کاربر مشکوک نباشد، پس از زده شدن تیک کپچا، اصلا فرم کپچا برای کاربر نمایش داده نمی شود اما اگر گوگل به کاربر مشکوک بشود، آن موقع است که فرم کپچا را خواهد دید. این مورد از نظر UX بسیار بهتر از موارد دیگر است. ما باز هم از نسخه v2 استفاده خواهیم کرد.

برای پیاده سازی این نوع از کپچا ابتدا باید تگ زیر را درون تگ <head> از فایل HTML خود قرار دهید:

<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback" defer></script>

توجه داشته باشید که در آخر نام فایل از خصوصیت onload استفاده کرده ام. یعنی زمانی که این اسکریپت بارگذاری شود، به صورت خودکار متدی به نام onloadCallback را صدا خواهد زد. این متد درون خود اسکریپت تعریف نشده است و شما باید آن را تعریف کنید بنابراین مهم نیست که اسم آن حتما onloadCallback باشد یا چیز دیگری. زمانی که این متغیر را تعریف می کنید باید درون آن تابعی به نام ()grecaptcha.execute را صدا بزنید که مسئول زدن تیک کپچا است (در ادامه به صورت عملی می بینید). این متد درون اسکریپت کپچا تعریف شده است بنابراین باید دقیقا به همین نام باشد. در نهایت یک تابع به نام setResponse خواهیم داشت (یا هر نامی که شما دوست داشته باشید) تا پاسخ اعتبار سنجی کپچا را دریافت کند. ما نتیجه اعتبارسنجی را درون یک فیلد hidden در فایل HTML خواهیم داشت که بعدا می بینید.

شما می توانید تمام این کدها را درون یک تگ script یا فایل اصلی جاوا اسکریپت خود بگذارید. مثال:

<script>
var onloadCallback = function() {
    grecaptcha.execute();
};

function setResponse(response) { 
    document.getElementById('captcha-response').value = response; 
}
</script>

برای کدهای HTML نیز باید کلاس g-recaptcha را داشته باشیم. همچنین به data-sitekey نیاز داریم چرا که این attribute مسئول نگهداری پاسخ اعتبارسنجی کپچا است. اسکریپت ما یک فیلد hidden خواهد داشت که پاسخ کپچا را در آن قرار می دهد و متد setResponse در کد بالا نیز دقیقا همین مقدار را می گیرد (آیدی 'captcha-response' همان آیدی است).

بنابراین نمونه کد HTML ما به شکل زیر خواهد بود:

<form action="" method="post">
    <input type="text" name="name" placeholder="Your name" required >
    <input type="email" name="email" placeholder="Your email address" required>
    <textarea name="message" placeholder="Type your message here...." required></textarea>
    
    <!-- Google reCAPTCHA widget -->
    <div class="g-recaptcha" data-sitekey="6Leb-lcUAAAAAGcIVh0g3OmILVSzm5_tNtT-x7Re" data-badge="inline" data-size="invisible" data-callback="setResponse"></div>
    
    <input type="hidden" id="captcha-response" name="captcha-response" />
    <input type="submit" name="submit" value="SUBMIT">
</form>

تا این قسمت، مرحله اعتبارسنجی کپچا را انجام داده ایم و حالا باید پاسخ آن را بررسی کنیم. من کد PHP ساده آن را برایتان قرار می دهم:

<?php
// Google reCaptcha secret key
$secretKey  = "9Seh-ksJHSUysHGST8y4KSg0UisYS7A3QUjsGHSt";

$statusMsg = '';
if(isset($_POST['submit'])){
    if(isset($_POST['captcha-response']) && !empty($_POST['captcha-response'])){
        // Get verify response data
        $verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secretKey.'&response='.$_POST['captcha-response']);
        $responseData = json_decode($verifyResponse);
        if($responseData->success){
            //کد خود را با منطق مورد نظرتان ارسال کنید. مشکلی نیست.
  
            $statusMsg = 'Your contact request have submitted successfully.';
        }else{
            $statusMsg = 'Robot verification failed, please try again.';
        }
    }else{
        $statusMsg = 'Robot verification failed, please try again.';
    }
}
?>

توجه کنید که secretKey های موجود در کدهای بالا فقط نمونه هستند و باید با secretKey های خودتان عوض شوند. در کد بالا ابتدا از همه متغیری به نام statusMsg را داریم که فعلا خالی است. سپس بررسی می کنیم که captcha-response تعریف شده و خالی نباشد (کاربر کپچا را انجام داده باشد). در مرحله بعد باز هم درخواست را به همراه اطلاعات به آدرس زیر می فرستیم:

https://www.google.com/recaptcha/api/siteverify?secret='.$secretKey.'&response='.$_POST['captcha-response']

پس از باز کردن رشته JSON اگر پاسخ گوگل success بود یعنی کاربر کپچا را به درستی انجام داده است و ما مشکلی نداریم. حالا می توانید فرم خود را ثبت و تکمیل کنید، در غیر این صورت به کاربر خطایی نمایش داده اید.

استفاده از نسخه سوم (V3)

اگر دوست دارید از نسخه سوم استفاده کنید من قالب کدی را برایتان قرار می دهم تا بتوانید از آن استفاده کنید. از آنجایی که فرآیند کلی را در روش های قبل توضیح دادیم فکر نمی کنم نیاز به توضیح دوباره باشد اما به هر حال به صورت خلاصه توضیح کلی را ارائه می کنم. ابتدا یک حساب کاربری ساخته و site key و secret key را دریافت کنید. سپس یک تگ اسکریپت به شکل زیر را به صفحه HTML خود اضافه کنید. نمونه:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Google reCAPTCHA v3</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css">
    <script src="https://www.google.com/recaptcha/api.js?render=YOUR_RECAPTCHA_SITE_KEY"></script>
    <script>
        grecaptcha.ready(function () {
            grecaptcha.execute('YOUR_RECAPTCHA_SITE_KEY', { action: 'contact' }).then(function (token) {
                var recaptchaResponse = document.getElementById('recaptchaResponse');
                recaptchaResponse.value = token;
            });
        });
    </script>
</head>

در کد بالا به جای YOUR_RECAPTCHA_SITE_KEY باید site key خودتان را قرار دهید. همانطور که مشخص است متدی به نام grecaptcha.ready در کد بالا اجرا می شود (پس از بارگذاری کامل اسکریپت). خصوصیت action نیز باید به صفحه اصلی اشاره کند که برای من contact است چرا که یک فرم ساده تماس با ما (contact us) داریم. در نهایت یک input مخفی یا hidden داریم که آیدی recaptchaResponse را دارد. من این آیدی را دریافت کرده ام و مقدار آن را برابر token گذاشته ام. token یک توکن یا شماره خاص است که اسکریپت کپچا برای هر کاربر به صورت جداگانه ایجاد می کند. این توکن ها پس از 2 دقیقه باطل می شوند بنابراین شاید بهتر باشد که متد grecaptcha.execute را هنگام ثبت شدن فرم (onSubmit) صدا بزنید چرا که اگر کاربر پر کردن فرم را بیشتر از 2 دقیقه طول بدهد، توکن او باطل خواهد شد (بستگی به طولانی بودن یا کوچک بودن فرم شما دارد).

کد HTML فرم من به شکل زیر است:

<body>

    <section class="section">
        <div class="container">
            <div class="columns">
                <div class="column is-half">

                    <form method="POST">

                        <h1 class="title">
                            reCAPTCHA v3 example
                        </h1>

                        <div class="field">
                            <label class="label">Name</label>
                            <div class="control">
                                <input type="text" name="name" class="input" placeholder="Name" required>
                            </div>
                        </div>

                        <div class="field">
                            <label class="label">Email</label>
                            <div class="control">
                                <input type="email" name="email" class="input" placeholder="Email Address" required>
                            </div>
                        </div>

                        <div class="field">
                            <label class="label">Message</label>
                            <div class="control">
                                <textarea name="message" class="textarea" placeholder="Message" required></textarea>
                            </div>
                        </div>

                        <div class="field is-grouped">
                            <div class="control">
                                <button type="submit" class="button is-link">Send Message</button>
                            </div>
                        </div>

                        <input type="hidden" name="recaptcha_response" id="recaptchaResponse">

                    </form>

                </div>
            </div>
        </div>
    </section>

</body>

</html>

فیلد hidden من را در کد بالا می بینید. نهایتا کد PHP را برای اعتبارسنجی می نویسیم:

<?php // Check if form was submitted:
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['recaptcha_response'])) {

    // Build POST request:
    $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
    $recaptcha_secret = 'YOUR_RECAPTCHA_SECRET_KEY';
    $recaptcha_response = $_POST['recaptcha_response'];

    // Make and decode POST request:
    $recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
    $recaptcha = json_decode($recaptcha);

    // Take action based on the score returned:
    if ($recaptcha->score >= 0.5) {
        // Verified - send email
    } else {
        // Not verified - show form error
    }

} ?>

همانطور که می بینید همه چیز مانند قبل از به جز پاسخ دریافتی از سرور! نسخه سوم کپچای گوگل بر اساس یک سیستم امتیازدهی کار می کند. یعنی پاسخ گوگل به شما امتیازی بین 0 تا 1 است و بر اساس گفته گوگل امتیاز 0 یعنی حتما ربات است و امتیاز 1 به احتمال زیاد یک کاربر عادی است بنابراین سخت گیری های اولیه به خود شما بستگی دارد. من فعلا برای نمونه گفته ام هر امتیاز بالا 0.5 را انسان در نظر بگیر و فرم را ثبت کن.

در ضمن پاسخ دریافتی از سمت سرور برای چنین حالتی، شیء ای با قالب زیر است:

{
  "success": true|false,
  "challenge_ts": timestamp,  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
  "hostname": string,         // the hostname of the site where the reCAPTCHA was solved
  "error-codes": [...]        // optional
}

به طور مثال برای من چنین چیزی برگردانده شده است:

{
    [success] => 1
    [challenge_ts] => 2018-11-01T22:31:14Z
    [hostname] => recaptcha.local
    [score] => 0.9
    [action] => contact
}

اطلاعات بیشتر در documentation رسمی گوگل

نکات تکمیلی

پس از گذشت زمانی مشخص می توانید به صفحه آمار (analytics) در پنل کاربری خود بروید و تعداد درخواست های خود را مشاهده کنید. در این صفحه آمار جالبی را پیدا خواهید کرد، مثلا اینکه چند کاربر کپچای شما را درخواست داده و حل کرده اند.

اگر می خواهید کپچای شما به زبان فارسی باشد (مثلا به جای I’m not a robot بگوید «من یک ربات نیستم») می توانید پارامتر hl را در انتهای اسکریپت خود مشخص کنید. به طور مثال برای زبان فرانسه می گوییم:

<script src='https://www.google.com/recaptcha/api.js?hl=fr'></script>

یا برای زبان فارسی می گوییم:

<script src='https://www.google.com/recaptcha/api.js?hl=fa'></script>

شما می توانید لیست کامل زبان های پشتیبانی شده را در این صفحه از وب سایت رسمی گوگل کپچا پیدا کنید. البته اگر از کدهای خارجی جاوا اسکریپت استفاده می کنید و کد بالا برای شما کار نکرد، می توانید از این کد استفاده نمایید:

    function setCaptchaLang(lang) {

      const container = document.getElementById('captcha_container');

      // Get GoogleCaptcha iframe
      const iframeGoogleCaptcha = container.querySelector('iframe');

      // Get language code from iframe
      const actualLang = iframeGoogleCaptcha.getAttribute("src").match(/hl=(.*?)&/).pop();

      // For setting new language
      if (actualLang !== lang) {
        iframeGoogleCaptcha.setAttribute("src", iframeGoogleCaptcha.getAttribute("src").replace(/hl=(.*?)&/, 'hl=' + lang + '&'));
      }
    }

امیدوارم این مقاله به شما کمک کرده باشد.

نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.