آموزش پیاده سازی کپچای گوگل در وردپرس بدون نصب افزونه

آموزش پیاده سازی کپچای گوگل google recaptcha

در پست آموزشی امنیت وردپرس را به ریکپچای(Invisible reCaptcha) گوگل بسپارید! به طور کامل در رابطه با کپچای گوگل، تاریخچه و چرایی استفاده از آن صحبت کردیم، بنابراین در این مقاله بدون فوت وقت وارد مباحث اصلی می شویم.

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

هر چقدر یک وب سایت به افزونه های کمتری وابسته باشد به همان اندازه هم مشکلات کمتری خواهد داشت.

در این مطلب آموزشی می خواهیم به این سوال پاسخ دهیم:

چگونه گزینه “من ربات نیستم” را به فرم های وب اضافه کرده و اعتبارسنجی کنیم؟

قبل از شروع آموزش پیشنهاد می کنیم مقالات زیر را مطالعه فرمائید:

  1. روش صحیح و اصولی استفاده از jQuery در وردپرس
  2. امنیت وردپرس: نانس(Nonce) دیواری محکم در مقابل حملات CSRF
  3. دسترسی به داده های PHP در جاوا اسکریپت با wp_localize_script
  4. آموزش اعتبارسنجی درخواست های ایجکس از طریق نانس(Nonce)
  5. آموزش استفاده از ایجکس(jQuery Ajax) در وردپرس(مثال استان و شهر)

ثبت وب سایت در سرویس Google reCaptcha

برای اینکه بتوانید در فرم هایی همچون عضویت، تماس با ما، ارسال دیدگاه و … از کپچای گوگل استفاده نمائید لازم است مراحل زیر را انجام دهید.

ابتدا با اکانت جی میل تان به سرویس Google reCaptcha لاگین کنید، سپس مشابه تصویر زیر فیلدهای موردنیاز را تکمیل نمائید.

برای اعمال تغییرات روی دکمه SUBMIT کلیک کنید، گوگل بر اساس سرویس انتخابی شما Site Key و Secret Key را تولید می کند، این صفحه را نبندید چون در مرحله بعدی به آن احتیاج داریم.

تعریف ثوابت موردنیاز در وردپرس

حالا در فایل functions.php این ثوابت را تعریف کرده و مقادیر Site Key و Secret Key را جایگزین نمائید.

define( 'RECAPTCHA_SITE_KEY', '6LaknNUZ2t3DAAt5AwnskdLHyD54KDpsAUAAnR27' );
define( 'RECAPTCHA_SECRET_KEY', '6Ldnjx0oNAAAPsAUwf4OotEZT0AA7ORCrKUQUemn' );

افزودن اسکریپت Google reCaptcha در وردپرس

برای استفاده از کپچای گوگل لازم است اسکریپت موردنیاز آن را در قالب وب سایت تان enqueue نمائید. از فایل custom.js در مراحل بعدی استفاده خواهیم کرد، فرض کردیم این فایل در دایرکتوری js قالب ایجاد شده است.

کدهای زیر را به فایل functions.php اضافه کنید.

function modiredev_theme_scripts() {

    wp_enqueue_script( 'modiredev-custom-js', 
        get_template_directory_uri() . '/js/custom.js',
        array( 'jquery' ), '', true );

    wp_enqueue_script( 'modiredev-google-recaptcha', 
        'https://www.google.com/recaptcha/api.js?hl=fa', array() );
}

add_action( 'wp_enqueue_scripts', 'modiredev_theme_scripts' );

ایجاد فرم ورود اطلاعات

در این مرحله یک فرم وب ساده تعریف می کنیم که کاربر از طریق آن نام و نام خانوادگی خود را وارد کرده، تیک گزینه “من ربات نیستم” را انتخاب و فرم را submit می کند.

فرم فوق را می توانید از طریق شورتکد یا یک صفحه اختصاصی در اختیار کاربران قرار دهید.

<form id="my_form"
      method="post"
      data-url="<?php echo admin_url( 'admin-ajax.php' ); ?>"
      data-nonce="<?php echo wp_create_nonce( 'my-form-nonce' ) ?>">

    <div class="form-group">
        <label for="user_full_name">نام و نام خانوادگی</label>
        <input type="text"
               class="form-control"
               id="user_full_name"
               name="user_full_name">
    </div>

    <div class="form-group">
        <label for="g-recaptcha"></label>
        <div id="g-recaptcha"
             class="g-recaptcha"
             data-sitekey="<?php echo RECAPTCHA_SITE_KEY; ?>">
        </div>
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-success btn-lg">ارسال</button>
    </div>
    
</form>

ارسال داده های فرم از طریق ایجکس(Ajax)

هنگامی که کاربر روی دکمه “ارسال” کلیک می کند داده های فرم را از طریق ایجکس دریافت و به سرور ارسال می کنیم.

برای این منظور کدهای زیر را به فایل custom.js اضافه نمائید.

(function ($) {
    $('#my_form').on('submit', function (e) {
        e.preventDefault();

        var form = $(this),
            full_name = form.find('#user_full_name').val().trim(),
            ajaxUrl = form.data('url'),
            nonce = form.data('nonce'),
            recaptcha = form.find('#g-recaptcha-response').val().trim();

        $.ajax({
            url: ajaxUrl,
            type: 'post',
            data: {
                g_recaptcha_response: recaptcha,
                action: 'check_google_recaptcha'
            },
            success: function (response) {
                if (response.status) {
                    $.ajax({
                        url: ajaxUrl,
                        type: 'post',
                        data: {
                            user_full_name: full_name,
                            nonce: nonce,
                            action: 'process_user_data'
                        },
                        success: function (response) {
                        }
                    });
                }
            }
        });
    });
})(jQuery);

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

اگر دقت کرده باشید در هیچ کجای فرم از آیدی g-recaptcha-response استفاده نکردیم، این آیدی مربوط به TextArea باکس “من ربات نیستم” است که به صورت خودکار توسط اسکریپت گوگل ایجاد و رندر می شود.

اعتبارسنجی google reCaptcha در سمت سرور

در قالب وب سایت تان یک فایل به نام google-recaptcha.php در دایرکتوری includes ایجاد کرده و کدهای زیر را در آن کپی نمائید.

توجه داشته باشید که Secret Key تولید شده در مراحل قبل را حتما در فیلد secret آرایه ارسالی به تابع http_build_query قرار دهید.

function modiredev_check_google_recaptcha(){

    $response = array(
        'status' => false,
        'message' => ''
    );

    $recaptcha = wp_strip_all_tags(
        trim(
            isset($_POST['g_recaptcha_response'])
                ? $_POST['g_recaptcha_response'] : ''
        )
    );

    if (empty($recaptcha)) {
        $response['message'] = 'گزینه من ربات نیستم را انتخاب کنید';
        wp_send_json($response);
    }

    $recaptcha_content = http_build_query(
        array(
            'secret' => GR_SECRET_KEY,
            'response' => $recaptcha,
            'remoteip' => $_SERVER['REMOTE_ADDR']
        )
    );

    $recaptcha_opts =
        array(
            'http' => array(
                'method' => 'POST',
                'header' => 'Content-type: application/x-www-form-urlencoded',
                'content' => $recaptcha_content
            )
        );

    $recaptcha_context = stream_context_create($recaptcha_opts);
    $recaptcha_response = json_decode(
        file_get_contents(
            "https://www.google.com/recaptcha/api/siteverify",
            false,
            $recaptcha_context
        ),
        true
    );

    if ($recaptcha_response['success']) {
        $response['status'] = true;
        wp_send_json($response);
    }

    $response['message'] = 'ریکپچا خطا دارد';
    wp_send_json($response);
}

add_action('wp_ajax_nopriv_check_google_recaptcha', 'modiredev_check_google_recaptcha');
add_action('wp_ajax_check_google_recaptcha', 'modiredev_check_google_recaptcha')

برای اینکه وردپرس از وجود این فایل مطلع شود آن را به functions.php اضافه کنید.

require get_template_directory() . '/includes/google-recaptcha.php';

جمع بندی

اعتبارسنجی سمت کلاینت(JS/Client Side Validation) را فراموش نکنید، بهتر است قبل از ارسال داده ها به سرور چک های لازم را انجام داده و پیغام مناسب را به کاربر نمایش دهید.

اعتبار سنجی سمت سرور(Server Side Validation) را به عنوان یک مرحله پردازشی حیاتی در نظر بگیرید، اگر کاربری جاوا اسکریپت مرورگر خود را غیرفعال کرده باشد حداقل در سمت سرور داده های ارسالی او اعتبارسنجی شود.

اعتبار سنجی سمت کلاینت را به منظور بهبود تجربه کاربری(UX) و اعتبارسنجی سمت سرور را برای مسائل امنیتی پیاده سازی کنید.

برچسب ها
سعید یاورنیا 117 نوشته 117 دیدگاه

توسعه دهنده وب، کارشناس ارشد نرم افزار.

دیدگاه ‌ها

  • امین ۵ خرداد ۱۳۹۹ - ۱۲:۵۲

    ممنون از لطفتون مهندس یاورنیا عزیز بسیار مطلب مفیدی بود

  • امین ۱۴ خرداد ۱۳۹۹ - ۰۰:۰۵

    سلام وقت بخیر مهندس یاورنیا عزیز
    من یک فایل را به وسیله تابعget_templete_partداخل یک فایل دیگه inclodکردم ولی اون فایل که inclod شده به داده های فایل که داخلشinclod شده دسترسی نداره ولی وقتی مستقیمinclodمیکنم بدون تابعget_templete_partبه داده ها فایلی که داخلشincloudشده دسترسی داره علتش چی می تونه باشه این خطا
    ممنون

    • سعید یاورنیا ۱۶ خرداد ۱۳۹۹ - ۱۵:۵۶

      سلام امین عزیز.
      موردی که شما اشاره کردی bug نیست، در سورس تابع get_template_part در مستندات وردپرس این تابع یکی از توابع require و require_once رو فراخوانی می کنه، چون این فراخوانی در بدنه تابع get_template_part انجام میشه عملا داده ها و متغیرها به صورت سراسری در دسترس نیستند.
      برای تست این موضوع کافیه به صورت زیر عمل کنی، متغیر hi$ رو داخل test.php تعریف کن.


      function sayHi(){
      require 'template-parts/test.php';
      }
      sayHi();
      echo $hi;

دیدگاهتان را بنویسید.

نشانی ایمیل شما منتشر نخواهد شد، بخش‌های موردنیاز با * مشخص شده‌اند.