PHP: защита страниц только для участников с помощью системы входа в систему
Проблемы с предоставленным кодом
В предоставленном коде PHP встречается несколько проблем, которые затрудняют его функциональность:
- Извлечение результатов запроса: вместо использования $data1 = $conn->query($sql1); правильный подход — использовать $data = mysqli_fetch_array($conn->query($sql1)); или $data = $conn->query($sql1)->fetch_array(); для получения результатов запроса.
- Подключение и выполнение базы данных: соединение с базой данных должно быть установлено с использованием $total = $data = 0; перед выполнением каких-либо запросов.
- Синтаксис MySQLi: Запрос для вставки токена должен использовать обратные кавычки () вокруг имен таблиц и столбцов (токены INSERT INTO (tk, gauth) VALUES (?,? )`) вместо одинарных кавычек.
- Аутентификация пользователя: Логика аутентификации должна возвращать результат запроса, а не полагаться на логические значения ($result = $conn->query($sql3)->fetch_array();).
- Генерация токена: существующий метод генерации токенов небезопасен, поскольку он использует openssl_random_pseudo_bytes(). Вместо этого в коде следует использовать криптографически безопасный генератор случайных чисел (CSPRNG), например random_bytes().
Предлагаемое решение
- Упрощение операций с базой данных: Используйте один запрос для получения информации о пользователе и проверки учетных данных.
- Используйте подготовленные операторы: Bind параметры для предотвращения уязвимостей SQL-инъекций.
- Безопасное генерирование токенов: используйте random_bytes() или аналогичную функцию для безопасной генерации токенов.
- Сохраняйте данные аутентификации в сеансе : сохраните токен аутентификации в переменной сеанса вместо cookie.
- Проверка токенов: выполните запрос к базе данных к таблице токенов, чтобы проверить предоставленный токен.
Улучшенный код
Следующее пересмотренный код устраняет выявленные проблемы и обеспечивает более безопасную систему входа на страницу только для участников:
connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Prepare statement for user authentication
$sql_auth = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$sql_auth->bind_param("ss", $_POST['uname'], $_POST['pss']);
$sql_auth->execute();
$result_auth = $sql_auth->get_result();
// Authenticate user
if ($result_auth->num_rows > 0) {
$user = $result_auth->fetch_assoc();
$correct = TRUE;
} else {
$correct = FALSE;
}
// Generate token
if ($correct === TRUE) {
$hex = bin2hex(random_bytes(3));
$_SESSION['auth'] = $hex;
$_SESSION['logstat'] = TRUE;
}
// Close connection
$conn->close();
?>