نحوه ایجاد ثبت نام امن در پی اچ پی و هش کردن رمز عبور

ترجمه و تالیف : عرفان حشمتی
تاریخ انتشار : 30 آبان 99
خواندن در 2 دقیقه
دسته بندی ها : پی اچ پی

ایجاد فرم ثبت نام کاربر امن با پی اچ پی کاری ترسناک به نظر می‌رسد. چگونه می‌توان ازSQL Injection و سایر روش‌های هک محافظت کرد. با کمال تعجب، تنها با چند مرحله و اقدامات احتیاطی می‌توانید احتمال موفقیت در حملات را تا حد زیادی کاهش دهید.

در این مقاله، من از طریق چند مرحله اساسی اما مهم برای ایجاد فرم ثبت نام قوی و ایمن در پی اچ پی با شما صحبت خواهم کرد.

<?php

// Replace $user and $pass with strong values for production
$host = 'localhost';
$db   = 'new_db';
$user = 'root';
$pass = '';

$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];
$dsn = "mysql:host=$host;dbname=$db";
try {
     $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
     throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

?>

با استفاده از PDO اتصال پایگاه داده خود را برقرار کنید. می‌توانید موارد بالا را کپی و پیست کنید و پیش بروید.

در مرحله بعد، شما باید از فرم ثبت نام ارائه شده فیلدها را بگیرید. من خودم فقط از کاربر می‌خواهم که نام، ایمیل و رمز عبور خود را تایید و ارسال کند.

<?php

// Get form field values
    $fname              = filter_input(INPUT_POST, 'fname', FILTER_SANITIZE_STRING);
    $email              = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
    $pwd                = filter_input(INPUT_POST, 'password');
    $pwd_confirm        = filter_input(INPUT_POST, 'confirm-password');

?>

اطمینان حاصل کنید که از FILTER_SANITIZE_STRING در رمز عبور استفاده نکنید زیرا گذرواژه کاربر را تایید نمی‌کنید. بعضی از افراد به ویژه کسانی که در حوزه فناوری فعالیت دارند، ممکن است دوست داشته باشد چیزی مانند '<script>' را به عنوان بخشی از رمز عبور خود داشته باشد.

<?php

$activation_key     = bin2hex(random_bytes(15));
$activation_link    = 'https://www.example.com/activate?id='.$activation_key.'&name='.$fname;

?>

یک کلید فعال سازی ایجاد کنید و از کاربران جدید بخواهید ثبت نام حساب خود را از طریق ایمیل تأیید کنند. با این کار تعداد حساب‌های هرزنامه بسیار کاهش می‌یابد. من از bin2hex برای ایجاد یک رشته 15 کاراکتری تصادفی استفاده کردم تا از بروز هرگونه مشکل در صورت ثبت نام تعداد زیادی از کاربران در سایت جلوگیری کند. همچنین نام کاربر را به رشته اضافه کردم، سپس می‌توانم از سمت سرور تأیید کنم.

<?php 

// Check if passwords match
    if ($pwd !== $pwd_confirm) {
        $errors[] = "Passwords don't match";
    }

    // Check if password is secure
    if (strlen($pwd) < 8) {
        $errors[] = "Password not long enough! Must be at least 8 characters long";
    }

    // Check if username equals password
    if ($fname === $pwd) {
        $errors[] = "Your name cannot be your password!";
    }

?>

اکنون در حال بررسی وجود خطاهای موجود در ارسال فرم هستیم. توجه داشته باشید که بررسی ایمن بودن رمز ورود در این مرحله بسیار پیچیده نیست. من توصیه می‌کنم بررسی‌های بیشتری را انجام دهید، به عنوان مثال حروف بزرگ و کوچک، حروف خاص و اعداد. می‌توانید این کار را با استفاده از یک عبارت منظم انجام دهید.

<?php 

// Check if email address exists in database
    $email_query = $pdo->prepare("SELECT count(1) FROM users WHERE email = :email");
    $email_query->bindParam(':email', $email);
    $email_query->execute();
    $email_found = $email_query->fetchColumn();
    if ($email_found) {
        $errors[] = "Your email address is associated with another account.";
    }

?>
 

همچنین بررسی می‌کنیم که آیا آدرس ایمیل از قبل در پایگاه داده وجود دارد یا خیر. وقتی مقادیر را از پایگاه داده خود SELECT یا به آن INSERT می‌کنید، همیشه از دستورات آماده استفاده کنید و پارامترها را ببندید تا از تزریق SQL جلوگیری شود.

<?php 

// If no errors, continue with user account creation
    if (!$errors)
    {   
        // Hash password
        $hashed_password = password_hash($pwd, PASSWORD_DEFAULT);

        // Create database entry
        $create_account = $pdo->prepare("INSERT INTO users (first_name,email,password, activation_key) VALUES (:fname, :email, :password, :activation_key)");
        $create_account->bindParam(':fname', $fname);
        $create_account->bindParam(':email', $email);
        $create_account->bindParam(':password', $hashed_password);
        $create_account->bindParam(':activation_key', $activation_key);
        $create_account->execute();

        // Send out activation email
        $to=$email;
        $subject="Activate your account";
        $from = 'no-reply@example.com';
        $body='Thank you for creating your account, '.$fname.'. Please click on the following link to activate your account: <a href="'.$activation_link.'">'.$activation_link.'</a>';
        $headers = "From:".$from;
        mail($to,$subject,$body,$headers);

        // Redirect user to the dashboard
        header("Location: /dashboard.php");
        exit;
    }

?>

اگر در ارسال فرم هیچ خطایی مشاهده نکرده‌اید، زمان ایجاد یک حساب جدید فرا رسیده است. برای انجام این کار، ابتدا باید رمز عبور ارسال شده را هش کنید. هرگز گذرواژه‌های متن ساده را در پایگاه داده خود ذخیره نکنید. سپس می‌توانید دستور را آماده کرده، پارامترها را متصل کرده و برای وارد کردن مقادیر در پایگاه داده اجرا کنید.

آخرین و اما مهمترین بخش، شما می‌خواهید ایمیل فعال سازی را ارسال کنید. در این مثال، من از تابع mail() استفاده کردم اما ممکن است بخواهید به جای آن از PHPMailer استفاده کنید. همچنین ممکن است بخواهید از ()http_build_query برای ساخت رشته فعال سازی در صورت عدم سازگاری نام کاربری استفاده کنید.

اکنون می‌توانید از مراحل ثبت نام خارج شده و منتظر بمانید تا کاربر حساب خود را فعال کند یا آن‌ها را به صفحه بعدی هدایت کنید، به عنوان مثال داشبورد. با این حال، توجه داشته باشید که اگر بخواهید ریدایرکت کنید، می‌توانید جلسه (session) را شروع کنید.

امیدوارم این آموزش برایتان مفید بوده باشد. اگر هرگونه سوال یا نظری دارید، در بخش زیر با ما در میان بگذارید.

منبع

گردآوری و تالیف عرفان حشمتی
آفلاین
user-avatar

عرفان حشمتی هستم، مهندس سخت افزار و برنامه نویس و طراح وب سایت، علاقه مند به دنیای آی تی و تکنولوژی، همچنین در حوزه ادیت فیلم و تصویر مطالعه و تمرین می کنم.

دیدگاه‌ها و پرسش‌ها

برای ارسال نظر لازم است ابتدا وارد سایت شوید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید