wiki:ImportantCase0

Регистрација на нов член

Актери

  • Нов корисник

Чекор 1

Новиот корисник треба да ја пополни регистрацијата со внесување на лични податоци како што се username, email и password

<?php
session_start();

if ($_SERVER["REQUEST_METHOD"] !== "POST") {
    header("Location: /Sign&Log.php");
    exit();
}

// Basic input validation
if (empty($_POST['email'])) {
    header("Location: /Sign&Log.php?error=INVALID_EMAIL");
    exit();
}
if (empty($_POST['username'])) {
    header("Location: /Sign&Log.php?error=INVALID_USERNAME&email=" . urlencode($_POST['email']));
    exit();
}
if (empty($_POST["password"])) {
    header("Location: /Sign&Log.php?error=INVALID_PASSWORD&email=" . urlencode($_POST['email']) . "&username=" . urlencode($_POST['username']));
    exit();
}

// Sanitize and validate inputs
$input_name = trim(htmlspecialchars($_POST['username']));
$input_email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
$input_password = $_POST['password'];
$role = 'Member';

// Additional validation
if (!$input_email) {
    header("Location: /Sign&Log.php?error=INVALID_EMAIL");
    exit();
}

// Password strength validation
if (strlen($input_password) < 8) {
    header("Location: /Sign&Log.php?error=WEAK_PASSWORD&email=" . urlencode($_POST['email']) . "&username=" . urlencode($input_name));
    exit();
}

// Username validation (alphanumeric and underscore only)
if (!preg_match('/^[a-zA-Z0-9_]+$/', $input_name)) {
    header("Location: /Sign&Log.php?error=INVALID_USERNAME_FORMAT&email=" . urlencode($_POST['email']));
    exit();
}

try {
    require 'connect.php';

    $conn->beginTransaction();

    // Check for existing username
    $stmt = $conn->prepare("CALL register_user(:username, :email, :password, :role)");
    // Hash password
    $hashed_password = password_hash($input_password, PASSWORD_ARGON2ID, [
        'memory_cost' => 65536,
        'time_cost' => 4,
        'threads' => 3
    ]);

    $stmt->bindParam(':username', $input_name, PDO::PARAM_STR);
    $stmt->bindParam(':email', $input_email, PDO::PARAM_STR);
    $stmt->bindParam(':password', $hashed_password, PDO::PARAM_STR);
    $stmt->bindParam(':role', $role, PDO::PARAM_STR);

    $stmt->execute();

    // Commit the transaction
    $conn->commit();

    // Set session variables for automatic login
    session_regenerate_id(true);
    $_SESSION['username'] = $input_name;
    $_SESSION['userid'] = $conn->lastInsertId();
    $_SESSION['role'] = $role;
    $_SESSION['last_activity'] = time();
    $_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];

    // Redirect to homepage after successful registration
    header("Location: ./HomePage.php");
    exit();

} catch (PDOException $e) {
    // Roll back the transaction if something failed
    $conn->rollBack();
    error_log("Registration error: " . $e->getMessage());
    header("Location: /Sign&Log.php?error=SERVER_ERROR");
    exit();
}


?>
  • Се користи POST метод за испраќање на податоците од формата. Кодот врши основна валидација на внесените податоци (email, корисничко име, лозинка) и проверува дали се соодветни (на пр., дали лозинката е доволно силна, дали email-от е валиден). Ако сите податоци се точни, кодот ги чисти и валидира внесените вредности, а потоа ги зачувува во базата на податоци преку SQL процедура (CALL register_user). Лозинката се хашира со PASSWORD_ARGON2ID за подобар ентитет. Ако регистрацијата е успешна, корисникот се логира автоматски и се пренасочува кон почетната страница (HomePage.php). Ако има грешка, корисникот се враќа на страницата за регистрација со соодветна порака за грешка. Се користат сесии за следење на активност и зачувување на корисничките податоци.

Чекор 2

По успешна регистрација корисникот се најавува со своето корисничко име и лозинка за да да пристапи до платформата.

<?php
session_start();
session_regenerate_id(true);

// Rate limiting check (session-based)
if (isset($_SESSION['login_attempts']) && $_SESSION['login_attempts'] > 5) {
    $timeout = 300; // 5 minutes timeout
    if (time() - $_SESSION['last_attempt'] < $timeout) {
        header("Location: /Sign&Log.php?error=TOO_MANY_ATTEMPTS");
        exit();
    } else {
        $_SESSION['login_attempts'] = 0;
    }
}

// Input validation
if (empty($_POST['username']) || empty($_POST['password'])) {
    header("Location: /Sign&Log.php?error=INVALID_CREDENTIALS");
    exit();
}

require 'connect.php';

try {
    $conn->beginTransaction();

    $username = trim(htmlspecialchars($_POST['username']));
    
    // Using stored procedure instead of direct query
    $sql = "SELECT * FROM validate_login(:username)";
    $stmt = $conn->prepare($sql);
    $stmt->bindParam(':username', $username, PDO::PARAM_STR);
    $stmt->execute();
    
    if ($stmt->rowCount() <= 0) {
        $_SESSION['login_attempts'] = isset($_SESSION['login_attempts']) ? $_SESSION['login_attempts'] + 1 : 1;
        $_SESSION['last_attempt'] = time();

        $conn->rollBack();
        header("Location: /Sign&Log.php?error=INVALID_CREDENTIALS");
        exit();
    }

    $res = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!password_verify($_POST['password'], $res['password'])) {
        $_SESSION['login_attempts'] = isset($_SESSION['login_attempts']) ? $_SESSION['login_attempts'] + 1 : 1;
        $_SESSION['last_attempt'] = time();

        $conn->rollBack();
        header("Location: /Sign&Log.php?error=INVALID_CREDENTIALS");
        exit();
    }

    $conn->commit();

    // Session setup
    $_SESSION['username'] = $username;
    $_SESSION['userid'] = $res['userid'];
    $_SESSION['role'] = $res['role'];
    $_SESSION['last_activity'] = time();
    $_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];
    
    $_SESSION['login_attempts'] = 0;
    
    // Redirect based on role
    if ($res['role'] == 'Admin') {
        header("Location: ./Admin.php");
    } else {
        header("Location: ./HomePage.php");
    }
    
} catch (PDOException $e) {
    $conn->rollBack();
    error_log("Login error: " . $e->getMessage());
    header("Location: /Sign&Log.php?error=SERVER_ERROR");
    exit();
}
?>
  • Се користи POST метод за испраќање на корисничкото име и лозинка. Кодот вклучува ограничување на обиди за логирање (rate limiting) за да се спречи brute force напад. Ако корисникот има повеќе од 5 неуспешни обиди, се блокира за 5 минути.
  • Валидација на влез: Проверува дали корисничкото име и лозинката се пополнети.
  • Проверка на лозинката: Споредува ја внесената лозинка со хашираната лозинка во базата со password_verify.
  • Сесија: Ако логирањето е успешно, се поставуваат сесиски променливи (корисничко име, ID, улога, активност, IP адреса).
  • Пренасочување: Корисникот се пренасочува според неговата улога (Admin или обичен корисник).
  • Ако има грешка (на пр., погрешни credentials или серверска грешка), корисникот се враќа на страницата за логирање со соодветна порака за грешка.

Чекор 3

Преглед на успешен Чекор 2

Last modified 6 weeks ago Last modified on 02/24/25 15:56:13

Attachments (5)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.