كيف تنشئ نظام تسجيل دخول يحد المحاولات الفاشلة؟
السؤال:
رقم السؤال: 578
الإجابة:
لإنشاء نظام تسجيل دخول في PHP يمنع المستخدم من المحاولة لأكثر من ثلاث مرات خاطئة خلال فترة زمنية محددة، يمكن استخدام الجلسات (Sessions) أو قاعدة بيانات لتخزين عدد المحاولات ووقت الحظر.
إعداد جدول قاعدة البيانات
إنشاء جدول لتتبع المحاولات الفاشلة ووقت الحظر:
CREATE TABLE login_attempts (
id INT AUTO_INCREMENT PRIMARY KEY,
user_ip VARCHAR(45) NOT NULL,
attempts INT DEFAULT 0,
last_attempt DATETIME,
blocked_until DATETIME
);
الكود الرئيسي للتحقق من تسجيل الدخول
<?php
session_start();
$mysqli = new mysqli("localhost", "username", "password", "database");// التحقق من الاتصال
if ($mysqli->connect_error) {
die("Connection failed: " . $mysqli->connect_error);
}// الحصول على عنوان IP الخاص بالمستخدم
$user_ip = $_SERVER['REMOTE_ADDR'];
$time_now = new DateTime();// استعلام المحاولات الفاشلة
$stmt = $mysqli->prepare("SELECT attempts, blocked_until FROM login_attempts WHERE user_ip = ?");
$stmt->bind_param("s", $user_ip);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();if ($row) {
$attempts = $row['attempts'];
$blocked_until = $row['blocked_until'] ? new DateTime($row['blocked_until']) : null;// التحقق مما إذا كان المستخدم محظورًا
if ($blocked_until && $time_now < $blocked_until) {
echo "تم حظرك. حاول مرة أخرى بعد " . $blocked_until->format('H:i:s');
exit;
}
} else {
$attempts = 0;
$blocked_until = null;
}// معالجة تسجيل الدخول
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];// استعلام للتحقق من صحة بيانات الدخول
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();if ($user) {
// نجاح تسجيل الدخول
echo "مرحبًا بك، " . htmlspecialchars($username);
// إعادة تعيين المحاولات
$stmt = $mysqli->prepare("DELETE FROM login_attempts WHERE user_ip = ?");
$stmt->bind_param("s", $user_ip);
$stmt->execute();
} else {
// زيادة عدد المحاولات
$attempts++;
if ($attempts >= 3) {
$blocked_until = $time_now->add(new DateInterval('PT10M'));
} else {
$blocked_until = null;
}// تحديث أو إدراج المحاولات
if ($row) {
$stmt = $mysqli->prepare("UPDATE login_attempts SET attempts = ?, last_attempt = ?, blocked_until = ? WHERE user_ip = ?");
$stmt->bind_param("isss", $attempts, $time_now->format('Y-m-d H:i:s'), $blocked_until ? $blocked_until->format('Y-m-d H:i:s') : null, $user_ip);
} else {
$stmt = $mysqli->prepare("INSERT INTO login_attempts (user_ip, attempts, last_attempt, blocked_until) VALUES (?, ?, ?, ?)");
$stmt->bind_param("siss", $user_ip, $attempts, $time_now->format('Y-m-d H:i:s'), $blocked_until ? $blocked_until->format('Y-m-d H:i:s') : null);
}
$stmt->execute();// رسالة خطأ
if ($attempts >= 3) {
echo "تم حظرك لمدة 10 دقائق بسبب المحاولات الفاشلة.";
} else {
echo "اسم المستخدم أو كلمة المرور غير صحيحة. لديك " . (3 - $attempts) . " محاولات متبقية.";
}
}
}
?><!-- نموذج تسجيل الدخول -->
<form method="POST">
اسم المستخدم: <input type="text" name="username" required>
كلمة المرور: <input type="password" name="password" required>
<button type="submit">تسجيل الدخول</button>
</form>
شرح الكود
- التحقق من عدد المحاولات: يتم تخزين عدد المحاولات وعنوان IP ووقت الحظر في قاعدة البيانات.
- الحظر عند الفشل: إذا تجاوز المستخدم الحد المسموح به، يتم حظره لمدة 10 دقائق.
- إعادة تعيين المحاولات: إذا تم تسجيل الدخول بنجاح، يتم حذف المحاولات الفاشلة.