پی ایچ پی میں ایک بنیادی لاگن سسٹم تیار کریں

ویب ڈیویلپرز ایسی یوٹیلٹی قسم کی ایپلی کیشنز بناتے رہتے ہیں جنہیں وہ لوکل ہوسٹ پر بھی استعمال کرتے ہیں اور حسب ضرورت پبلک ویب سرور پر بھی اپ لوڈ کرتے ہیں۔ چونکہ ایسی ایپلی کیشنز سے عموماً ڈیٹا پراسیسنگ اور فائل ہینڈلنگ وغیرہ نوعیت کے کام لیے جاتے ہیں اس لیے ویب ڈیویلپرز نہیں چاہتے کہ پبلک ویب سرور پر ان کے علاوہ انہیں کوئی اور استعمال کرے۔ لیکن ایسی عمومی اور مختصر ایپلیکیشنز کے لیے ایک پورا لاگن سسٹم انسٹال کرنا ضرورت سے بڑا کام بن جاتا ہے۔ عام طور پر اس کا حل اس طرح کیا جاتا ہے کہ ایپلیکیشن کے فولڈر کا ایسا مشکل نام رکھا جائے جو کوئی اور شخص اندازے سے معلوم نہ کر سکے۔ اگرچہ یہ طریقہ کافی حد تک کام کرتا ہے لیکن اگر ایسی کوئی ایپلیکیشن آپ کسی اور کے کمپیوٹر پر استعمال کریں یا کوئی اور آپ کا کمپیوٹر استعمال کرتا ہو تو پھر یہ طریقہ زیادہ فائدہ مند نہیں رہتا۔ چنانچہ اس ٹٹوریل میں ہم PHP میں ڈیٹابیس استعمال کیے بغیر ایک سنگل یوزر لاگن سسٹم تیار کرنے کا عمل دیکھیں گے، ایسا سسٹم جس کا فولڈر آپ اپنے ویب سرور پر ڈال کر ایک یا بیک وقت ایک سے زیادہ ایپلیکیشنز کے لیے استعمال میں لا سکتے ہیں۔


اس ٹٹوریل کو مختصر رکھنے کی غرض سے لاگن سسٹم کی خوبصورتی کے لیے CSS کوڈ استعمال نہیں کیا گیا۔ درج ذیل لاگن سسٹم کے اسکرین شاٹس دکھائے گئے ہیں اور اس کے بعد کوڈ کا تعارف کرایا گیا ہے۔


ایپلیکیشن کے ساتھ یہ لاگن سسٹم کیسے منسلک کریں؟

اپنی ایپلیکیشن کی ہر فائل کے شروع میں درج ذیل لائن شامل کریں۔ اس کا فائل پاتھ آپ حسب ضرورت تبدیل کر سکتے ہیں۔

<?php
    
include("../admin/authenticate.php");
?>


لاگن سسٹم کا کوڈ اور اس کا مختصر تعارف

درج ذیل لاگن سسٹم کی فائلز کی فہرست دی جا رہی ہے، ان پر کلک کر کے ان کے کوڈ کی مختصر وضاحت دیکھیں:

config.php
authenticate.php
login.php
index.php
change_password.php
logout.php
unguessable.pas


config.php

اس فائل میں لاگن سسٹم کی سیٹنگز کے لیے کانسٹینٹ ویری ایبلز ڈیفائن کیے گئے ہیں اس لیے یہ فائل لاگن سسٹم کی ہر فائل میں شامل کی گئی ہے۔ یہ کانسٹینٹ ویری ایبلز مختلف سیٹنگز پر مشتمل ہیں۔ مثلاً لاگن سسٹم کا فولڈر پاتھ، جس فائل میں لاگن کی معلومات محفوظ ہیں اس کا نام، پاسورڈ کے لیے کم سے کم حروف کی حد، اور مختلف ایررز واقع ہونے پر دکھائے جانے والے پیغامات وغیرہ۔ کانسٹینٹ ویری ایبلز پر مشتمل ایسی فائل استعمال کرنے کا فائدہ یہ ہوتا ہے کہ آپ کو سیٹنگز تبدیل کرنے کے لیے مختلف فائلز میں جا کر انہیں تلاش نہیں کرنا پڑتا۔ ایک اور فائدہ یہ ہے کہ اگر آپ لاگن سسٹم کے پیغامات کا ترجمہ کسی اور زبان میں کرنا چاہیں تو یہ کام ایک ہی فائل میں کیا جا سکتا ہے۔

<?php
define
("APP_URL""http://localhost/admin/");
define("LOGIN_INFO_FILE""unguessable.pas");
define("PASSWORD_MIN_LENGTH"5);
define("MSG_PASSWORD_MIN_LENGTH""<div style='color:red;'>Minimum required length of password is 5.</div>");
define("MSG_INVALID_LOGIN""<div style='color:red;'>Invalid username or password.</div>");
define("MSG_REQUIRED_INFO""<div style='color:red;'>Please provide all the required information.</div>");
define("MSG_RETYPED_PASSWORD""<div style='color:red;'>Password and retyped password do not match.</div>");
define("MSG_OLD_PASSWORD""<div style='color:red;'>Invalid old password.</div>");
define("MSG_PASSWORD_UPDATED""<div style='color:green'>Password updated successfully.</div>");
define("MSG_LOGGED_IN""<div>You are logged in, welcome to single user login system.</div>");
define("MSG_LOGGED_OUT""<div>Logged out successfully.</div>");
define("MSG_LOGIN_FILE_READ""<div style='color:red;'>Could not fetch login information.</div>");
define("MSG_LOGIN_FILE_WRITE""<div style='color:red;'>Could not write data, please check permissions.</div>");
?>

authenticate.php

یہ فائل ایپلی کیشن کی ہر اس فائل میں شامل کی جائے گی جسے ہم لاگڈ اِن ایریا میں شامل کرنا چاہتے ہیں۔

<?php
include_once("config.php");

session_start();

if (!isset(
$_SESSION["loggedin"])) {
    
header("location: " APP_URL "login.php");
}
?>

login.php

جیسا کہ نام سے ظاہر ہے اس فائل میں لاگن فارم مہیا کیا گیا ہے ۔یوزر اس ویب فارم میں یوزرنیم اور پاسورڈ مہیا کر کے ویب سرور پر بھیجے گا۔ ویب سرور پر PHP کوڈ کی مدد سے یوزر کی بھیجی ہوئی لاگن معلومات کو unguessable.pas فائل میں محفوظ معلومات کے ساتھ میچ کیا جائے گا۔ اگر یہ معلومات درست ہوئیں تو پھر ایک SESSION_$ ویری ایبل سیٹ کر کے یوزر کو لاگن کر دیا جائے گا اور پھر یوزر کو لاگن سسٹم کے index.php فائل کی طرف بھیج دیا جائے گا۔


<?php     

include_once("config.php");

if (isset(
$_POST["submit_button"])) {
    
    
$error 0;

    
$username = isset($_POST["username"]) ? trim($_POST["username"]) : "";
    
$password = isset($_POST["password"]) ? trim($_POST["password"]) : "";
    if (empty(
$username) || empty($password)) {
        
$message MSG_REQUIRED_INFO;
        
$error 1;
    }

    
$file_handler fopen(LOGIN_INFO_FILE"r");
    if (!
$file_handler) {
        
$message MSG_LOGIN_FILE_READ;
        
$error 1;
    } else {
        
$file_data fread($file_handlerfilesize(LOGIN_INFO_FILE));
        
fclose($file_handler);
        
$login_info explode("|"$file_data);
        
$stored_username = isset($login_info[0]) ? trim($login_info[0]) : "";
        
$stored_password = isset($login_info[1]) ? trim($login_info[1]) : "";
        if (
$username != $stored_username || !password_verify($password$stored_password)) {
            
$message MSG_INVALID_LOGIN;
            
$error 1;
        }
    }

    if (
$error == 0) {
        
session_start();
        
$_SESSION["loggedin"] = true;
        
header("Location: index.php");
        exit;
    }

}
?>

<!doctype html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    
    <h3>Login</h3>
    
    <?php if (isset($message)) print $message?>
    
    <br>
    
    <form method="post" action="login.php">

        Username<br>
        <input type="text" id="username" name="username" 
            value="<?php if (isset($username)) print $username?>" autofocus required><br><br>
    
        Password<br>
        <input type="password" id="password" name="password" 
            value="<?php if (isset($password)) print $password?>" required><br><br>

        <input type="submit" name="submit_button" value="Login">

    </form>

</body>
</html>
?>

index.php

یہ فائل لاگن سسٹم کا ہوم پیج ہے جس میں پاسورڈ تبدیل کرنے اور لاگ آؤٹ کرنے کے لنکس موجود ہیں۔ چونکہ لاگن ہونے کے بعد یوزر اس فائل کی طرف بھیجا جاتا ہے اس لیے اس میں آپ اپنی ان تمام ایپلی کیشنز کے لنکس شامل کر سکتے ہیں جنہیں اس لاگن سسٹم کے تحت لانا چاہتے ہیں۔


<?php

include_once("config.php");
include_once(
"authenticate.php");

?>

<!doctype html>
<html>
<head>
    <title>User home</title>
</head>
<body>
    <a href="change_password.php">Change password</a> &nbsp; &nbsp;
    <a href="logout.php">Logout</a> &nbsp; &nbsp;
    <hr>

    <h3>User profile</h3>

    <p><?php print MSG_LOGGED_IN?></p>
    
    <p>
        <a href="http://localhost/app1">Application 1</a><br>
        <a href="http://localhost/app2">Application 2</a><br>
        <a href="http://localhost/app3">Application 3</a><br>
    </p>

</body>
</html>
?>

change_password.php

اس فائل میں مہیا کیے گئے ویب فارم کی مدد سے یوزر اپنا پاسورڈ تبدیل کر سکتا ہے۔ جب فارم ویب سرور پر بھیجا جائے گا تو پہلے پرانے پاسورڈ کی تصدیق کی جائے گی کہ وہ درست ہے یا نہیں، پھر نئے پاسورڈ کی درستگی چیک کی جائے گی، سب درست ہونے کی صورت میں نیا پاسورڈ unguessable.pas فائل میں محفوظ کر دیا جائے گا۔


<?php     

include_once("config.php");
include_once(
"authenticate.php");

if (isset(
$_POST["submit_button"])) {

    
$error 0;

    
$old_password = isset($_POST["old_password"]) ? trim($_POST["old_password"]) : "";
    
$new_password1 = isset($_POST["new_password1"]) ? trim($_POST["new_password1"]) : "";
    
$new_password2 = isset($_POST["new_password2"]) ? trim($_POST["new_password2"]) : "";

    if (empty(
$old_password) || empty($new_password1) || empty($new_password2)) {
        
$message MSG_REQUIRED_INFO;
        
$error 1;
    }

    
$file_handler fopen(LOGIN_INFO_FILE"r");
    if (!
$file_handler) {
        
$message MSG_LOGIN_FILE_READ;
        
$error 1;
    } else {
        
$file_data fread($file_handlerfilesize(LOGIN_INFO_FILE));
        
fclose($file_handler);
        
        
$login_info explode("|"$file_data);
        
$stored_username = isset($login_info[0]) ? trim($login_info[0]) : "";
        
$stored_password = isset($login_info[1]) ? trim($login_info[1]) : "";

        if (
$new_password1 != $new_password2) {
            
$message MSG_RETYPED_PASSWORD;
            
$error 1;
        } else if (
strlen($new_password1) < PASSWORD_MIN_LENGTH) {
            
$message MSG_PASSWORD_MIN_LENGTH;
            
$error 1;
        } else if (!
password_verify($old_password$stored_password)) {
            
$message MSG_OLD_PASSWORD;
            
$error 1;
        }
    }

    if (
$error == 0) {
        
$new_password_hash password_hash($new_password1PASSWORD_DEFAULT);
        
$updated_file_data $stored_username "|" $new_password_hash;
        
$file_handler fopen(LOGIN_INFO_FILE"w");
        if (!
$file_handler) {
            
$message MSG_LOGIN_FILE_WRITE;
        } else {
            
fwrite($file_handler$updated_file_data);
            
fclose($file_handler);            
            
$message MSG_PASSWORD_UPDATED;
            unset(
$old_password);
            unset(
$new_password1);
            unset(
$new_password2);
        }
    }
}

?>

<!doctype html>
<html>
<head>
    <title>Change password</title>
</head>
<body>
    
    <h3>Change password</h3>
    
    <?php if (isset($message)) print $message?>
    
    <form method="post" action="change_password.php">
        <br>
        Old password<br>
        <input type="password" id="old_password" name="old_password" 
            value="<?php if (isset($old_password)) print $old_password?>" required autofocus><br><br>

        New password<br>
        <input type="password" id="new_password1" name="new_password1" 
            value="<?php if (isset($new_password1)) print $new_password1?>" required><br><br>

        Retype new password<br>
        <input type="password" id="new_password2" name="new_password2" 
            value="<?php if (isset($new_password2)) print $new_password2?>" required><br><br>

        <input type="submit" name="submit_button" value="Update">
    </form>
    
    <p><a href="index.php">User profile</a></p>

</body>
</html>
?>

logout.php

یوزر جب لاگ آؤٹ لنک پر کلک کرے گا تو اس فائل میں PHP کے session_destroy فنکشن کی مدد سے سیشن ختم کر دیا جائے گا جس کے نتیجے میں یوزر لاگ آؤٹ ہو جائے گا۔


<?php 

include_once("config.php");
session_start();
session_destroy();

?>

<html>
<head>
    <title>Logged out</title>
</head>
<body>

    <p><?php print MSG_LOGGED_OUT?></p>

    <p><a href="login.php">Login</a></p>

</body>
</html>
?>

unguessable.pas

یہ وہ فائل ہے جس میں یوزرنیم اور پاسورڈ محفوظ کیے جاتے ہیں۔ اگر آپ چاہیں تو اس فائل کا نام تبدیل کر کے ایسا نام رکھ سکتے ہیں جو کوئی اور شخص اندازے سے معلوم نہ کر سکے۔ لیکن اگر کوئی پبلک ویب سرور پر یہ فائل دیکھ بھی لے تو کوئی حرج نہیں کیونکہ اس میں PHP کے password_hash فنکشن کی مدد سے پاسورڈ کی ہیش ویلیو محفوظ کی گئی ہے جو براہ راست کسی کام کی نہیں ہے، یہ ویلیو تبھی استعمال ہو سکتی ہے جب PHP کے password_verify فنکشن کو اس ہیش ویلیو کے ساتھ اصل پاسورڈ بھی مہیا کیا جائے۔ درج ذیل آپ دیکھ رہے ہیں کہ اس فائل میں یوزرنیم کے ساتھ پاسورڈ کی ہیش ویلیو محفوظ کی گئی ہے۔

admin|$2y$10$U2Fr8U9p0i1KSB6omvXXtu6KXFR4NDU7rETir/VDSfpF44dhLOxu6


اگر پاسورڈ بھول جائے تو کیا کریں؟

لاگن سسٹم کا ڈیفالٹ یوزر نیم اور پاسورڈ دونوں admin ہیں۔ جیسا کے اوپر ذکر ہو چکا ہے کہ آپ پاسورڈ تبدیل کر سکتے ہیں لیکن اگر آپ یہ تبدیل کیا ہوا پاسورڈ بھول جائیں تو اس کے لیے آپ کو ایک عارضی پاسورڈ کی ہیش ویلیو جنریٹ کرنا ہوگی اور پھر اس ویلیو کو unguessable.pas فائل میں محفوظ کرنا ہوگا۔ اس کے بعد آپ لاگن سسٹم کے ذریعے اس عارضی پاسورڈ کو تبدیل کر سکتے ہیں۔ عارضی پاسورڈ کی ہیش ویلیو جنریٹ کرنے کے لیے درج ذیل فنکشن استعمال کریں۔

<?php
    
print password_hash("temporarypassword"PASSWORD_DEFAULT);
?>


مزید اقدامات کی ضرورت

  • اس لاگن سسٹم میں SQL injection سے بچنے کی کوشش نہیں کی گئی کیونکہ ہم کوئی ڈیٹابیس استعمال نہیں کر رہے۔ اگر آپ اسے تبدیل کر کے اس میں SQLite یا کوئی اور ڈیٹابیس استعمال کرنا چاہیں تو پھر آپ کو ایس کیو ایل انجیکشن سے بچنے کے لیے اقدامات کرنا ہوں گے۔
  • ہم نے Session hijacking سے بچنے کے لیے بھی کچھ نہیں کیا کیونکہ ایسی انفرادی ویب ایپلیکیشنز کے لاگن سسٹم تک رسائی کے لیے شاید کوئی اتنا تکلف نہیں کرتا۔ لیکن اگر آپ ایسا کرنا چاہیں تو پھر PHP کے اس مقصد کے لیے فنکشنز استعمال کر سکتے ہیں مثلاً ایک عام فنکشن session_regenerate_id ہے جو ہر براؤزر کال پر سیشن کا آئی ڈی نمبر تبدیل کر دیتا ہے، جس کا فائدہ یہ ہے کہ پھر براؤزر اور ویب ایپلیکیشن کے درمیان سیشن برقرار رکھنے والی Cookie چوری کر کے کسی اور براؤزر میں استعمال نہیں کی جا سکتی۔
Categories: