Активный
- Тема Автор
- #1
Руководство по созданию системы регистрации, входа и управления сессиями пользователей.
Регистрация пользователя
Вход в систему
Проверка авторизации
Выход из системы
Защита от CSRF
Защита от брутфорса
Запоминание пользователя (Remember Me)
Сброс пароля
Двухфакторная аутентификация
Валидация данных
Система аутентификации - основа безопасности веб-приложений. Эти примеры показывают все необходимые компоненты для безопасной работы с пользователями.
Регистрация пользователя
Код:
<?php
function registerUser($username, $email, $password) {
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
// Проверка существования
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ? OR email = ?");
$stmt->execute([$username, $email]);
if ($stmt->fetch()) {
return false;
}
// Хеширование пароля
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// Создание пользователя
$stmt = $pdo->prepare("INSERT INTO users (username, email, password, created_at) VALUES (?, ?, ?, NOW())");
return $stmt->execute([$username, $email, $hashedPassword]);
}
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['register'])) {
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
if (registerUser($username, $email, $password)) {
echo "Регистрация успешна";
} else {
echo "Ошибка регистрации";
}
}
?>
Вход в систему
Код:
<?php
session_start();
function loginUser($username, $password) {
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$stmt = $pdo->prepare("SELECT id, username, password FROM users WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
return true;
}
return false;
}
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['login'])) {
$username = $_POST['username'];
$password = $_POST['password'];
if (loginUser($username, $password)) {
header('Location: dashboard.php');
exit;
} else {
echo "Неверные данные";
}
}
?>
Проверка авторизации
Код:
<?php
session_start();
function isLoggedIn() {
return isset($_SESSION['user_id']);
}
function requireLogin() {
if (!isLoggedIn()) {
header('Location: login.php');
exit;
}
}
function getCurrentUser() {
if (!isLoggedIn()) {
return null;
}
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
return $stmt->fetch();
}
// Использование
requireLogin();
$user = getCurrentUser();
?>
Выход из системы
Код:
<?php
session_start();
function logout() {
$_SESSION = array();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 3600, '/');
}
session_destroy();
}
if (isset($_GET['logout'])) {
logout();
header('Location: login.php');
exit;
}
?>
Защита от CSRF
Код:
<?php
session_start();
function generateCSRFToken() {
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
function validateCSRFToken($token) {
return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}
// В форме
$csrfToken = generateCSRFToken();
echo '<input type="hidden" name="csrf_token" value="' . $csrfToken . '">';
// При обработке
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!validateCSRFToken($_POST['csrf_token'])) {
die('CSRF token validation failed');
}
// Обработка формы
}
?>
Защита от брутфорса
Код:
<?php
function checkLoginAttempts($username, $maxAttempts = 5, $lockoutTime = 300) {
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
// Удаление старых попыток
$stmt = $pdo->prepare("DELETE FROM login_attempts WHERE username = ? AND time < ?");
$stmt->execute([$username, time() - $lockoutTime]);
// Подсчет попыток
$stmt = $pdo->prepare("SELECT COUNT(*) as count FROM login_attempts WHERE username = ?");
$stmt->execute([$username]);
$result = $stmt->fetch();
if ($result['count'] >= $maxAttempts) {
return false; // Заблокирован
}
return true;
}
function recordLoginAttempt($username, $success) {
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
if (!$success) {
$stmt = $pdo->prepare("INSERT INTO login_attempts (username, time, ip) VALUES (?, ?, ?)");
$stmt->execute([$username, time(), $_SERVER['REMOTE_ADDR']]);
}
}
// Использование
if (!checkLoginAttempts($username)) {
die('Слишком много попыток входа. Попробуйте позже.');
}
$loginSuccess = loginUser($username, $password);
recordLoginAttempt($username, $loginSuccess);
?>
Запоминание пользователя (Remember Me)
Код:
<?php
function setRememberMe($userId) {
$token = bin2hex(random_bytes(32));
$expires = time() + (30 * 24 * 60 * 60); // 30 дней
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$stmt = $pdo->prepare("INSERT INTO remember_tokens (user_id, token, expires) VALUES (?, ?, ?)");
$stmt->execute([$userId, hash('sha256', $token), $expires]);
setcookie('remember_token', $token, $expires, '/', '', true, true);
}
function checkRememberMe() {
if (!isset($_COOKIE['remember_token'])) {
return false;
}
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$tokenHash = hash('sha256', $_COOKIE['remember_token']);
$stmt = $pdo->prepare("SELECT user_id FROM remember_tokens WHERE token = ? AND expires > ?");
$stmt->execute([$tokenHash, time()]);
$result = $stmt->fetch();
if ($result) {
$_SESSION['user_id'] = $result['user_id'];
return true;
}
return false;
}
// При входе
if (isset($_POST['remember_me'])) {
setRememberMe($userId);
}
// При загрузке страницы
if (!isLoggedIn()) {
checkRememberMe();
}
?>
Сброс пароля
Код:
<?php
function generateResetToken($email) {
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$stmt = $pdo->prepare("SELECT id FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch();
if (!$user) {
return false; // Не показываем что email не существует
}
$token = bin2hex(random_bytes(32));
$expires = time() + 3600; // 1 час
$stmt = $pdo->prepare("INSERT INTO password_resets (user_id, token, expires) VALUES (?, ?, ?)");
$stmt->execute([$user['id'], hash('sha256', $token), $expires]);
// Отправка email с токеном
$resetLink = "https://example.com/reset-password.php?token=" . $token;
mail($email, "Сброс пароля", "Перейдите по ссылке: " . $resetLink);
return true;
}
function resetPassword($token, $newPassword) {
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$tokenHash = hash('sha256', $token);
$stmt = $pdo->prepare("SELECT user_id FROM password_resets WHERE token = ? AND expires > ?");
$stmt->execute([$tokenHash, time()]);
$result = $stmt->fetch();
if (!$result) {
return false;
}
$hashedPassword = password_hash($newPassword, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("UPDATE users SET password = ? WHERE id = ?");
$stmt->execute([$hashedPassword, $result['user_id']]);
// Удаление токена
$stmt = $pdo->prepare("DELETE FROM password_resets WHERE token = ?");
$stmt->execute([$tokenHash]);
return true;
}
?>
Двухфакторная аутентификация
Код:
<?php
function generate2FACode($userId) {
$code = rand(100000, 999999);
$expires = time() + 300; // 5 минут
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$stmt = $pdo->prepare("INSERT INTO 2fa_codes (user_id, code, expires) VALUES (?, ?, ?)");
$stmt->execute([$userId, $code, $expires]);
// Отправка кода (email/SMS)
return $code;
}
function verify2FACode($userId, $code) {
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$stmt = $pdo->prepare("SELECT id FROM 2fa_codes WHERE user_id = ? AND code = ? AND expires > ?");
$stmt->execute([$userId, $code, time()]);
$result = $stmt->fetch();
if ($result) {
// Удаление использованного кода
$stmt = $pdo->prepare("DELETE FROM 2fa_codes WHERE id = ?");
$stmt->execute([$result['id']]);
return true;
}
return false;
}
?>
Валидация данных
Код:
<?php
function validateRegistration($username, $email, $password) {
$errors = [];
// Валидация имени пользователя
if (empty($username) || strlen($username) < 3) {
$errors[] = "Имя пользователя должно быть не менее 3 символов";
}
if (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) {
$errors[] = "Имя пользователя может содержать только буквы, цифры и подчеркивание";
}
// Валидация email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Неверный формат email";
}
// Валидация пароля
if (strlen($password) < 8) {
$errors[] = "Пароль должен быть не менее 8 символов";
}
if (!preg_match('/[A-Z]/', $password)) {
$errors[] = "Пароль должен содержать хотя бы одну заглавную букву";
}
if (!preg_match('/[0-9]/', $password)) {
$errors[] = "Пароль должен содержать хотя бы одну цифру";
}
return $errors;
}
?>
Система аутентификации - основа безопасности веб-приложений. Эти примеры показывают все необходимые компоненты для безопасной работы с пользователями.