باسم الله الرحمان الرحيم
قُل لِلَّذِينَ كَفَرُواْ إِن يَنتَهُواْ يُغْفَرْ لَهُم مَّا قَدْ سَلَفَ وَإِنْ يَعُودُواْ فَقَدْ مَضَتْ سُنَّةُ الأَوَّلِينِ
سورة الأنفال الآية 38
السلام عليكم و رحمة الله و بركاته
لا يخفى على أصحاب / مبرمجي المواقع الخطر الكبير الذي يشكله تنفيذ عملية مكلفة للسيرفر بشكل مفرط في التكرار و خاصة إذا كانت العملية مرتبطة بقاعدة البيانات.
في كثير من الحالات تعتبر هده العملية ثغرة قاتلة يمكن من خلالها اختراق الموقع بالكامل . و في أفضل الأحوال تعليق الموقع مؤقتا بسبب ارتفاع الضغط load على السيرفر
مثلا في برنامج المنتديات vbulletin تسمح لوحة التحكم للمشرف العام تحديد مدة معينة لكل عملية بحت . بحيث يمكن للمشرف العام منع الزائر / العضو من إنجاز أكتر من عملية بحت خلال 20 ثانية . و ما كل هدا إلا بسبب وعي مبرمجي vbulletin بخطورة العملية
لهدا أقترح عليكم في هدا الموضوع التعرف على أسهل طريقة لحماية الموقع من الأوامر المزعجة (spam)
التطبيق سيكون على بيئة البرمجة php و باعتماد قاعدة بيانات mysql . و بإمكان المبرمجين الدين يعتمدون على بيئة برمجية مختلفة استخلاص الفكرة و تطبيقها حسب خبرتهم
فعلى بركة الله نبدأ
أولا سنحتاج لجدول في قاعدة البيانات لتسجيل جميع العمليات التي يتم تنفيذها على الموقع و افتراضيا ستكون الحقول المطلوبة هي :
id: رقم العملية
type: نوع العملية : (بحت . إرسال موضوع . تحميل ملف ....)
awner: الفاعل - سيكون هو اسم المستخدم إدا كان مسجلا و يتم استخراجه من الجلسة
أما إدا كان المستخدم غير مسجل فيمكنك استخدام كود التحقق captcha (رابط الدرس) لتفادي الإغراق
time: وقت تنفيذ العملية
حسب ما سبق ستكون بنية الجدول هي :
كود:CREATE TABLE `antiload` ( `id` INT( 100 ) NOT NULL AUTO_INCREMENT , `type` VARCHAR( 100 ) NOT NULL , `awner` VARCHAR( 100 ) NOT NULL , `time` VARCHAR( 100 ) NOT NULL , UNIQUE ( `id` ) ) ENGINE = MYISAM ;
هدا مع اعتبار أن antiload هو اسم الجدول
الآن . كيف يتم تسجيل العمليات؟
مباشرة بعد تنفيذ أي عملية يتم تنفيذ استعلام إلى قاعدة البيانات يملأ الحقول في جدول antiload
لنفترض أن العملية التي تم تنفيذها هي: البحت
على سبيل المثال
مباشرة بعد هده العملية ننفذ افتراضيا الاستعلام التاليكود PHP:
$search = $_POST['search'];
$lo=mysql_query("select * from topic where topic='%$search%'");
لا أضن أنني في حاجة لتوضيح مصدر المتغيرات التي استخدمتها في الاستعلام الأخيركود PHP:
if($lo){
mysql_query("INSERT INTO antiload(type,awner,time)VALUES('search','$user','$time')");
}
أما $lo فهو المتغير المرتبط بتنفيذ عملية البحت و قد قمنا بربطه بعملية البحت الأولى و تمريره إلى الدالة الشرطية if في الكود الأخير بحيث لا يتم إدخال المعلومات إلى جدول antiload إلا في حالة تحقق الشرط
إدا تم تنفيذ العملية بنجاح فمن المفترض أن نجد التالي في الجدول الذي أنشأناه
الآن تم إدخال المعلومات إلى الجدول
تبقى أمامنا الخطوة الحاسمة و الأهم و هي :
كيف نستثمر هده المعلومات في منع الإغراق (spam)
نبقى مع المثال الأول : ( البحت )
كود PHP:
$search = $_POST['search'];
$lo=mysql_query("select * from topic where topic='%$search%'");
قبل تنفيذه مباشرة علينا التحقق من أن المستخدم لم يقم بعملية مشابهة مند 20 ثانية
كيف؟
نحدد وقتا أقدم من التاريخ الحالي بـ 20 ثانية . و الطريقة معروفة :
بعد حصولنا على المتغير $Lasttime يتوجب علينا الرجوع إلى قاعدة البيانات بالاستعلام التالي :كود PHP:
$Lasttime = time()-20;
هل تم إنجاز عملية بحت بعد الوقت $Lasttime من طرف نفس المستخدم؟
هدا سيعطينا عمليات البحت التي قام بها نفس المستخدم خلال فترة لا تزيد عن 20 ثانية.كود PHP:
$result=mysql_query("SELECT type, awner, time FROM antiload WHERE type='search' and awner='$user' and time>'$Lasttime'");
لنحسب عددها عن طريق دالة mysql_num_rows()
ادا كان عدد عمليات البحت التي تم إنجازها أكبر من 0 فينبغي منع المستخدم من تكرار العملية عن طريق دالة إيقاف التنفيذ die()كود PHP:
$count=mysql_num_rows($result);
كود PHP:
if($count>0){
die("عفوا . لا يمكنك إنجاز أكتر من عملية بحت في أقل من 20 ثانية");
}
في المرفقات متال جد مبسط لصفحة لا يمكنك اعادة طلب محتواها الا بعد مرور 20 تانية
في حالة نقل الموضوع يرجى دكر المصدر
و السلام عليكم