كيفية استخدام reCAPTCHA في التطبيقات
لمحاربة السخام كلنا قد مر علينا أسلوب أو أكثر من أساليب
الكابتشا CAPTCHA عند إبحارنا على الشبكة. فعند التسجيل في المواقع أو طرح
التعليقات، تأتينا بعض صور الكلمات أو الأحرف المقطعة والملونة. وبعض
الأحيان، يتم استخدام أساليب أخرى، كعرض بعض الصور واختيار أنسب صورة
للسؤال المطروح. كل هذا يتم للتحقق ما إذا كان المستخدم بشراً وليس آلةً.
رﻱكابتشا أتت بمفهوم جديد، ونقلت الكابتشا نقلة نوعية. فمع حفاظها على
السبب الرئيس وهو التفريق بين البشر والآلة، ومن ثم الحماية من
السخام.
فهي تقوم بعرض كلمات إنجليزية مفهومة، وليس بعض الأحرف والأرقام
العشوائية. والسبب وراء ذلك هو محاولة الشركة رقمنة الكتب التي كتبت قبل
اختراع الحاسوب. وتحوليها إلى كتب إلكترونية يسهل أرشفتها والبحث فيها، عبر
المدخلات التي يكتبها المستخدمون بصورة كابتشا.
سأقوم في هذا المقال بشرح طريقة تطبيق رﻱكابتشا باستخدام 3 طرق مختلفة.
أولاً باستخدام PHP، وبعدها بتطبيق شكل مخصص ليتلائم أكثر مع شكل الموقع
المراد إدراج الخدمة فيه، وأخيراً باستخدام تقنية أجاكس AJAX.
كيف تساعد رﻱكابتشا على تحويل الكتب القديمة إلى كتب رقمية؟كلما تم حل رﻱكابتشا من المستخدم، فإنه يساعد على تحويل الكتب القديمة
إلى كتب إلكترونية. وطريقة عملها سهلة. فهي تظهر صورة لكلمتين، الكلمة
الأولى هي كلمة يكون قد عجز أو تضارب في تحليلها أكثر من برنامج مختلف
لتحويل
صور
النصوص المكتوبة إلى نص رقمي OCR. والكلمة الثانية هي كلمة تكون
معروفة لدى النظام تسمى كلمة التحكم أو Control Word.
عندما يتم تقديم الكلمتين على حسب ترتيب عشوائي، يُسأل المستخدم لحلها.
فإذا تم مطابقة كلمة التحكم المعروفة بشكل صحيح، يفترض النظام أن الكلمة
الأخرى أيضاً صحيحة ويتم تسجيلها في قاعدة البيانات والاستفادة منها
مستقبلاً لتحويل المزيد من الكتب على شكل رقمي.
كيفية استخدام رﻱكابتشاتوفر مكتبة رﻱكابتشا
العديد
من التطبيقات والإضافات الملحقة لمعظم لغات البرمجة وتطبيقات الويب.
وفي هذا المقال، سنرى بعض أمثلة استخداماتها.
قبل الشروع في تطبيق الدروس، عليك أولاً القيام
بالتسجيل في الخدمة.
وبعد التسجيل يجب اختيار ما إذا كنت ترغب في استخدام هذه الخدمة على نطاق
واحد، أو عدة نطاقات إذا كنت مديراً لمواقع كثيرة. سيتم تزويدك بمفتاحين،
المفتاح العلني Public Key ويمكن إدراجه علناً على الصفحة لطلب ملفات واجهة
برمجة التطبيقات API، والمفتاح الخاص، والذي يجب عليك الاحتفاظ به سراً
للتواصل مع الخادم بإحدى لغات البرمجة على الويب.
عند الانتهاء،
حمّل
ملف المكتبة الجاهز على PHP. وفك ضغطه، سترى ملفاً باسم
recaptchalib.php وهو ما سيتم استخدامه وإدراجه في الأمثلة اللاحقة. فضلاً
تأكد أن يكون في مكان سهل ليتم إدراجه بدون عناء. شخصياً، أحب إدراجه في
مجلد خاص بالمكتبات أسميه includes. ولك الحرية في اختيار الأنسب.
استخدام رﻱكابتشا مع PHPعرضتحميلهذا تطبيق لاستخدام رﻱكابتشا على لغة PHP. عملية إنشاءه سهلة جداً.
سأبدء من منتصف الملف ومن ثم سألقي الضوء على أهم الأشياء لاحقاً.
الخطوة 1: إدراج المكتبة والمفاتيحview
sourceprint?1.require_once('recaptchalib.php');
2.
3.//استبدل XXXX مع المفاتيح التي موجودة على
http://recaptcha.net/api/getkey4.$publickey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
5.$privatekey
= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
نقوم بإدراج المكتبة بشكل عادي بواسطة require_once قبل نموذج الإدخال
في HTML، ومن ثم نقوم بتسجيل المفاتيح العلنية والخاصة في متغيرات لسهولة
طلبها لاحقاً من قبل البرنامج.
الخطوة 2: تعريب رسائل الخطأ في مصفوفةview
sourceprint?01.$error_ar =
array(
02. 'invalid-site-public-key' => 'المفتاح العلني للموقع
غير صحيح.',
03. 'invalid-site-private-key' => 'المفتاح الخاص للموقع
غير صحيح.',
04. 'invalid-request-cookie' => 'عامل التحدي للتحقق غير
صحيح.',
05. 'incorrect-captcha-sol' => 'حل كابتشا غير صحيح.',
06. 'verify-params-incorrect' =>
'عوامل التحقق كانت غير صحيحة.',
07. 'invalid-referrer' => 'المحيل غير صحيح.',
08. 'recaptcha-not-reachable' => 'خطأ من الخادم.'
09.);
قمت بتعريب بعض رسائل الأخطاء التي تظهر عند عدم التحقق من رﻱكابتشا،
ووضعها في مصفوفة لاستدعائها لاحقاً.
الخطوة 3: التحقق من مدخلات رﻱكابتشا ومطابقتهاview
sourceprint?01.$resp =
null;
02.
03.if ($_POST["submit"])
04.{
05. if (empty($_POST["name"]) || empty($_POST["recaptcha_response_field"]))
06. {
07. echo "بعض الحقول تركت فارغة!";
08. }
09. else
10. {
11. $resp = recaptcha_check_answer ($privatekey,
12. $_SERVER["REMOTE_ADDR"],
13. $_POST["recaptcha_challenge_field"],
14. $_POST["recaptcha_response_field"]);
15.
16. if ($resp->is_valid)
17. {
18. echo
"مبروك يا " . $_POST["name"] . "، لقد أجبت إجابة صحيحة!";
19. }
20. else
21. {
22. echo
$error_ar[$resp->error];
23. }
24. }
25. echo '
إعادة المحاولة.';
26.}
في البداية نتأكد أولاً إذا كان النموذج قد تم إرساله واستقباله في PHP
عبر المتغير $_POST["submit"].
حيث هذا المتغير سيكون مسجلاً إذا تم الإرسال عبر الضغظ على زر “موافق”
لأنه يحمل الخاصية name تساوي submit.
إذا تم ترك أحد الحقول فارغة، سواء الاسم عبر متغير $_POST["name"] أو حقل جواب رﻱكابتشا $_POST["recaptcha_response_field"].
سيتم إظهار رسالة توضيحية “بعض الحقول تركت فارغة!”. وإذا كانت الحقول
معبئة، سيتم متابعة التحقق.
الآن، سيتم إنشاء كائن باسم $resp
عبر استخدام دالة الإنشاء recaptcha_check_answer والتي تم إدراجها عبر
ملف recaptchalib.php. تهتم هذه الدالة بالاتصال بخادم رﻱكابتشا والتحقق
منها. تقبل عدد من المتغيرات. الأول هو المفتاح الخاص، الثاني هو عنوان IP
الخاص بالمستخدم، الثالث هو حقل معرفة نوع التحدي لرﻱكابتشا، والأخير هو
الجواب لتحدي رﻱكابتشا من قبل المستخدم.
بعدها نقوم بالتحقق من جواب الخادم، فإذا كان جواباً صحيحاً، سيحمل
متغير is_valid في كائن $resp
قيمة صحيحة true. أما إذا كان غير ذلك، فسيتم إرجاع خطأ للمستخدم وتعريبه
حسب نوعه باستخدام مصفوفة التعريب التي سبق إنشاءها.
أخيراً، نقوم بعرض رابط لإعادة المحاولة، وهو عبارة عن رابط فارغ فقط
لإعادة تحميل الصفحة.
الخطوة 4: عرض أو عدم عرض النموذجview
sourceprint?01. if (!isset($_POST["submit"])): ?>
02.
03.
04.
05. * ما هو اسمك؟
06.
type="text" id="name" name="name" size="30" />
07.
08.
09.
dir="ltr" style="float:right;">
10. * هل أنت انسان؟
11.
12.
13.
14.
style="clear:right;">* كل الحقول
مطلوبة!
15.
16.
17.
18.
19.
ستلاحظ في البداية السؤال عن متغير $_POST["submit"] عن ما إذا كان يحمل قيمة. فإذا لم يكن
يحمل أي قيمة، فمعناه أن المستخدم يعرض النموذج لأول مرة ولم يتم إرساله من
قبل. وإذا كان لا يحمل قيمة، فمعناه أن النموذج تم إرساله، لذلك سيتم
إخفاءه. ما يساعدنا على معرفة ذلك هو خاصية action في عنصر النموذج form
الفارغة. وهي حيلة بسيطة لإعادة تحميل نفس الصفحة عند إرسال النموذج،
وبعدها يتم تسجيل المتغيرات المطلوبة والتي تم شرحها في الخطوات السابقة.
يتم إدراج رﻱكابتشا بطريقة ديناميكية عبر دالة المساعدة
recaptcha_get_html والتي تعرض الشيفرة المطلوبة لعرض رﻱكابتشا وكافة
ملحقاتها.
الخطوة 5: تعريب رﻱكابتشاview
sourceprint?01.var RecaptchaOptions
= {
02. lang: 'ar',
03. custom_translations : {
04. visual_challenge
: "احصل على تحدي مرئي",
05. audio_challenge : "احصل على
تحدي مسموع",
06. refresh_btn :
"احصل على تحدي جديد",
07. instructions_visual : "اكتب
الكلمتين:",
08. instructions_audio
: "اكتب ما تسمعه:",
09. help_btn : "مساعدة",
10. play_again : "إعادة تشغيل
الصوت مرة أخرى",
11. cant_hear_this
: "تحميل الصوت بصيغة MP3",
12. incorrect_try_again : "خطأ.
أعد المحاولة."
13. }
14.};
سنضيف بعض الشيفرات الخاصة بتعريب محتوى رﻱكابتشا عن طريق الجافاسكربت
في أعلى الصفحة.
view
sourceprint?1..recaptchatable
label.recaptcha_input_area_text
2.{
3. text-align:right !important;
4. direction:rtl !important;
5.}
ومن ثم نضيف الشيفرات المتعلقة بالمظهر الجمالي بواسطة CSS أيضاً في
الأعلى.
استخدام رﻱكابتشا بشكل مخصصعرضتحميلسنرى الآن كيف يمكننا تخصيص شكل رﻱكابتشا بشكل يتلائم أكثر مع الموقع
المراد إدراجه فيه. ولأنها نفس طريقة الاستخدام مع PHP، فلن يتم إعادة شرح
عمل الإرسال والتحقق.
الخطوة 1: تعديل خيارات رﻱكابتشاview
sourceprint?01.var RecaptchaOptions
= {
02. theme: 'custom',
03. lang: 'ar',
04. custom_theme_widget: 'recaptcha_widget',
05. custom_translations : {
06. visual_challenge
: "احصل على تحدي مرئي",
07. audio_challenge : "احصل على
تحدي مسموع",
08. refresh_btn :
"احصل على تحدي جديد",
09. instructions_visual : "اكتب
الكلمتين:",
10. instructions_audio
: "اكتب ما تسمعه:",
11. help_btn : "مساعدة",
12. play_again : "إعادة تشغيل
الصوت مرة أخرى",
13. cant_hear_this
: "تحميل الصوت بصيغة MP3",
14. incorrect_try_again : "خطأ.
أعد المحاولة."
15. }
16.};
لا شيء جديد هنا، سوى خيارين، الخيار الأول theme يجب أن يحتوي على
custom ومعناها التخصيص. والخيار الآخر custom_theme_widget يجب أن يحتوي
على اسم المعرّف للتقسيمة التي ستحتوي على رﻱكابتشا.
الخطوة 2: عناصر التخصيص لكل جزئيةview
sourceprint?01.
action="" method="post">
02.
03. * ما هو اسمك؟
04.
type="text" id="name" name="name" size="30" />
05.
06.
07. * هل أنت انسان؟
08.
style="display:none">
09.
10.
11.
خطأ الرجاء
المحاولة مرة أخرى12. أدخل الكلمات الموجودة في المربع:
13.
class="recaptcha_only_if_audio">أدخل
الأرقام التي تسمعها:
14.
name="recaptcha_response_field" dir="ltr" />
15.
احصل
على كابتشا آخر16.
احصل على كابتشا مسموعة17.
احصل على كابتشا مرئية18.
مساعدة19.
20.
21.
22.
23.
24.
25.
height="300" width="500" frameborder="0">
26.
rows="3" cols="40" dir="ltr">
27.
28.
29. * كل الحقول
مطلوبة!
30.
31.
ستلاحظ إدراج العديد من التقاسيم والعناصر، وذلك لتخصيص الشكل تماماً
بما يناسب الموقع الذي تريد إدراج رﻱكابتشا فيه.
التقسيمة التي ستحتوي على رﻱكابتشا والتي لها معرّف id باسم
recaptcha_widget ستكون مخفية مبدأياً. وسيتم إظهارها باستخدام
الجافاسكربت.
لن أتطرق إلى الشرح التفصيلي لكل عنصر منها، ولكن مجملاً، بعض هذه
العناصر تظهر وتختفي بحسب طريقة رﻱكابتشا المستخدمة. فمثلاً عند التحويل
إلى رﻱكابتشا مسموعة، فستختفي كلمة “احصل على كابتشا مسموعة” ويتم
استبدالها بكلمة “احصل على كابتشا مرئية”.
عنصرا noscript وiframe يمكنانا من الرجوع بأمان إلى رﻱكابتشا بطريقة
iframe عند عدم تفعيل الجافاسكربت لدى المستخدم.
استخدام رﻱكابتشا مع الأجاكس AJAXعرضتحميلالخطوة 1: إنشاء ملف الوكيل لطلب معلومات رﻱكابتشا من الخادمview
sourceprint?01.02.require_once('recaptchalib.php');
03.//استبدل XXXX مع المفاتيح التي موجودة على
http://recaptcha.net/api/getkey04.$privatekey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
05.
06.//ُError Codes translated to arabic
07.$error_ar = array(
08. 'invalid-site-public-key' => 'المفتاح العلني للموقع
غير صحيح.',
09. 'invalid-site-private-key' => 'المفتاح الخاص للموقع
غير صحيح.',
10. 'invalid-request-cookie' => 'عامل التحدي للتحقق غير
صحيح.',
11. 'incorrect-captcha-sol' => 'حل كابتشا غير صحيح.',
12. 'verify-params-incorrect' =>
'عوامل التحقق كانت غير صحيحة.',
13. 'invalid-referrer' => 'المحيل غير صحيح.',
14. 'recaptcha-not-reachable' => 'خطأ من الخادم.'
15.);
16.
17.#
the response from reCAPTCHA
18.$resp = null;
19.
20.#
was there a reCAPTCHA response?
21.if (empty($_POST["recaptcha_response_field"]))
22.{
23. echo "حقل
الكابتشا مطلوب!";
24.}
25.else
26.{
27. $resp =
recaptcha_check_answer ($privatekey,
28. $_SERVER["REMOTE_ADDR"],
29. $_POST["recaptcha_challenge_field"],
30. $_POST["recaptcha_response_field"]);
31.
32. if ($resp->is_valid)
33. {
34. echo "مبروك، لقد أجبت إجابة صحيحة!";
35. }
36. else
37. {
38. echo $error_ar[$resp->error];
39. }
40.}
41.echo '
onclick="showRecaptcha('dynamic_recaptcha', 'submit', 'red');"
href="javascript:return false;">إعادة المحاولة.';
42.?>
سيتم إنشاء ملف مساعد للأجاكس نسميه ajax.recaptcha.php يهتم بطلب
المعلومة من خادم رﻱكابتشا وتقديم المعلومة. والسبب في إنشاء ملف كهذا يعمل
بمثابة الوكيل Proxy بين الأجاكس في موقعنا وخوادم رﻱكابتشا، هو أنه
لأسباب أمنية في المتصفحات، يتم منع طلب المعلومات مباشرة بطريقة الأجاكس
بين نطاقات مختلفة Cross domain.
ستلاحظ أنه لا اختلاف جذري بين هذا الملف، وملف رﻱكابتشا باستخدام PHP.
سوى أنه تم الاستغناء عن عناصر HTML، وذلك لأننا نريد فقط أن نأخذ معلومة
بسيطة.
الخطوة 2: إنشاء دوال المساعدة في طلب واستقبال الأجاكسview
sourceprint?01.function createRequestObject()
02.{
03. var req;
04. if(window.XMLHttpRequest)
05. {
06. req = new XMLHttpRequest();
07. }
08. else if(window.ActiveXObject)
09. {
10. req = new ActiveXObject("Microsoft.XMLHTTP");
11. }
12. else
13. {
14. alert('حصل
خطأ في طلب الصفحة...الرجاء المحاولة مرة أخرى وإذا لم تنفع جرب أن تنزل
نسخة جديدة من المتصفح');
15. }
16. return req;
17.}
18.
19.var http =
createRequestObject();
20.
21.function sendRequestPost(recaptcha_challenge_field,
recaptcha_response_field)
22.{
23. http.open('post', 'ajax.recaptcha.php');
24. http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
25. http.onreadystatechange = handleResponse;
26. http.send('recaptcha_challenge_field='+recaptcha_challenge_field+'&recaptcha_response_field='+recaptcha_response_field);
27.}
28.
29.function handleResponse()
30.{
31. document.getElementById("ajaxResp").style.display = 'block';
32. document.getElementById("dynamic_recaptcha").style.display
= 'none';
33. document.getElementById("submitDiv").style.display = 'none';
34. var ajaxTest
= document.getElementById("ajaxResp");
35. ajaxTest.innerHTML = 'جاري
التحقق...';
36. if(http.readyState
== 4 && http.status == 200)
37. {
38. var response
= http.responseText;
39. if(response)
40. {
41. ajaxTest.innerHTML
= response;
42. }
43. }
44.}
45.
46.function getAnswer()
47.{
48. sendRequestPost(Recaptcha.get_challenge(),
Recaptcha.get_response());
49.}
لن أتطرق إلى تفاصيل الطلب والاستقبال بالأجاكس كثيراً، فقد تم تغطيته
في
مقال سابق.
وهنا سنقوم فقط بطلب معلومة ما إذا كان تم التحقق من صحة رﻱكابتشا
باستخدام ملف ajax.recaptcha.php، عبر تقديم عدد من المتغيرات، وهي قيمة
حقل معرفة نوع التحدي لرﻱكابتشا. وحقل الجواب لتحدي رﻱكابتشا من قبل
المستخدم.
الخطوة 3: إعادة إنشاء رﻱكابتشا بتقنية الأجاكسview
sourceprint?01.function showRecaptcha(element)
02.{
03. //استبدل XXXX مع المفاتيح التي
موجودة على
http://recaptcha.net/api/getkey04. Recaptcha.create("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", element, {
05. theme: 'blackglass',
06. lang: 'ar',
07. custom_translations : {
08. visual_challenge
: "احصل على تحدي مرئي",
09. audio_challenge : "احصل على
تحدي مسموع",
10. refresh_btn :
"احصل على تحدي جديد",
11. instructions_visual : "اكتب
الكلمتين:",
12. instructions_audio
: "اكتب ما تسمعه:",
13. help_btn : "مساعدة",
14. play_again : "إعادة تشغيل
الصوت مرة أخرى",
15. cant_hear_this
: "تحميل الصوت بصيغة MP3",
16. incorrect_try_again : "خطأ.
أعد المحاولة."
17. },
18. callback: Recaptcha.focus_response_field
19. });
20. document.getElementById("dynamic_recaptcha").style.display
= 'block';
21. document.getElementById("ajaxResp").style.display = 'none';
22. document.getElementById("submitDiv").style.display = 'block';
23.}
يتم إنشاء رﻱكابتشا بالأجاكس عبر استدعاء كائن Recaptcha.create. حيث
يستقبل الكائن عدد من المتغيرات، أولاً المفتاح العلني، ثانياً اسم المعرّف
Id للعنصر المراد إدراج رﻱكابتشا فيه، وأخيراً الخيارات.
الخيارات تكون مشابهة تماماً للخيارات التي سبق شرحها باستخدام PHP. ولكن هناك خيار
جديد وهو callback. ويتيح هذا الخيار استدعاء دالة بعد الإنتهاء من تحميل
رﻱكابتشا.
في نهاية الدالة نقوم بإخفاء بعض العناصر وإظهار البعض الآخر لتحسين
قابلية الاستخدام.
الخطوة 4: عرض النموذج في HTMLview
sourceprint?1.
action="" method="post" onsubmit="getAnswer();return false;">
2. [url=https://joulyat.ahladalil.com/javascript:return false;]أظهر
الكابتشا![/url]
3.
dir="ltr" style="float:right;" id="dynamic_recaptcha">
4.
5.
class="button" value="موافق" />
6.
في عنصر النموذج form، تم استخدام حدث عند الإرسال onsubmit نستدعي دالة
getAnswer() والتي تهتم
بطلب المعلومة من الخادم وعرضها. من المهم إلحاق استدعاء الدالة بإرجاع خطأ
return false، والسبب هو أننا لا نريد أن يتم إرسال النموذج بطريقة HTML،
إنما بطريقة الأجاكس. وإرجاع الخطأ يوقف الإرسال عن طريق HTML.
في عنصر الرابط، سنرى إدراج الحدث عند النقر onclick، نستدعي الدالة
showRecaptcha وذلك لإظهار رﻱكابتشا في تقسيمة div التي لها معرّف
dynamic_recaptcha.
الخلاصةرأينا كيف باستخدامنا لرﻱكابتشا نضمن حماية المواقع من السخام، وفي نفس
الوقت مساعدة تحويل الكتب القديمة إلى كتب إلكترونية. ورأينا أيضاً كيف
يمكننا تطبيق رﻱكابتشا باستخدام 3 طرق مختلفة، باستخدام PHP فقط، من ثم
بتخصيص شكل رﻱكابتشا، وبعدها باستخدام تقنية الأجاكس.
إذا طبقتم الدرس في مواقع تديرونها، الرجاء منكم مشاركتنا إياها في
التعليقات. ما هو التالي؟ بما أنك قد وصلت إلى النهاية، ربما تكون قد أحببت المقال وأردت المزيد:
- دليلك السهل في تعلم استخدام مكتبة jQuery [الدرس الأخير]:
AJAX
- دليلك السهل في تعلم استخدام مكتبة jQuery [ الدرس الأول]
- [سجن
البرمجة] – كيفية الدخول فيه
- دليلك السهل في تعلم استخدام مكتبة jQuery [الدرس
الثاني]: الأحداث والتأثيرات
الوسوم:
AJAX ،
JavaScript ،
PHP ،
reCAPTCHA ،
سخام ،
كابتشا