Login form

I have a login page. Admin A for main branch and other Admin B, C and for branch B, C and D. Admin A can login to all branch while Admin B, C and D only can login into their own branch. But now what I can do is all admin only can login into their own branch. How can I do it so Admin A also can login into branch B, C and D?

This is my code.

if($_POST['username'] && $_POST['password'] &&  $_POST['txtbranch']) {
	$username  =  $_POST['username'];
	$password  =  $_POST['password'];
	$txtbranch =  $_POST['txtbranch'];
						
	$query = mysqli_query("select * from sysfile where username='".$username."' and password='".$password."' and branchid='".$txtbranch."' limit 1");
				 
	$count_user = mysqli_num_rows($query);
	if($count_user==1)
	{
		$row = mysqli_fetch_array($query);
		$_SESSION['userid'] = $row['userid'];
		$_SESSION['username'] = $row['username'];
		$_SESSION['pin'] = $row['pin'];
		$_SESSION['branchid'] = $_POST['txtbranch'];
		header("location:dashboard.php?success=1");
	}else{
			$error = 'Incorrect Username, Password and Branch.';	
		}
}

Try this:

<?php 
  session_start();

  if( (float)phpversion() >= 7):
    // PHP7 Null coalescing operator 
    $username  =  $_POST['username']  ??  NULL;
    $password  =  $_POST['password']  ??  NULL;
    $txtbranch =  $_POST['txtbranch'] ??  NULL;
  else:    
    $username  =  isset($_POST['username'])  ? $_POST['username']  : NULL;
    $password  =  isset($_POST['password'])  ? $_POST['password']  : NULL;
    $txtbranch =  isset($_POST['txtbranch']) ? $_POST['txtbranch'] : NULL;
  endif;  

  # DEBUG
    if(1):
      // TOGGLE to test for $admin
         $username  =  'ADMIN'; 
         $username  =  'username';
    
      $password  =  'password';
      $txtbranch =  'A';
    endif;  

  if( $username && $password &&  $txtbranch )
  {
   // WHAT ARE THE $branchid values ???
      // $branchid = ['A', 'B', 'C', 'D', 'E'];
    
    # Test FOR ADMOM
      $adminName = 'ADMIN';
      if($adminName===$username)
      {
         $sql  = ' 
           SELECT * 
           FROM   sysfile 
           WHERE  username="'  .$username  .'" 
           AND    password="'  .$password  .'" 
           AND    branchid>="' .$txtbranch .'" 
           LIMIT  1
        ';
        echo 'YES WE HAVE AN ADMIN';
      }else{
         $sql  = ' 
           SELECT * 
           FROM   sysfile 
           WHERE  username="'  .$username  .'" 
           AND    password="'  .$password  .'" 
           AND    branchid="' .$txtbranch .'" 
           LIMIT  1
        ';
        echo 'Just a user :(';
      }
    # DEBUG  
      echo '<pre>';print_r($sql); echo '</pre>';      
die;      


Why are passwords stored in plain text form, passwords should NEVER be stored in plain text form, they should ALWAYS be stored in hashed form.

Also you’re wide open to SQL Injection attacks as you’re letting user submitted data near the database without any sort of validation or santizing. At the very least, you should use prepared statements

3 Likes

Here’s something that I threw together seeing this question being asked over and over. It’s not working script and the script will have to be changed and modified in order to work. I just did it so a person could have an overall feel how-to-write-a-login script.

<?php

/*
 * This is just defining constants and this portion would normally go in a separate file off the root directory of
 * you project. I use an if statement to determine local and remote server that way I don't have to keep changing
 * the constants when I make modifications to the file and I finally move it to the remote server (production server).
 */
if (filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_SANITIZE_URL) == "localhost") {
    define('DATABASE_HOST', 'localhost'); // usually localhost
    define('DATABASE_NAME', 'cms');
    define('DATABASE_USERNAME', 'username');
    define('DATABASE_PASSWORD', 'password');
    define('DATABASE_TABLE', 'users');
} else {
    define('DATABASE_HOST', 'remote_database_host');
    define('DATABASE_NAME', 'remote_db_name');
    define('DATABASE_USERNAME', 'remote_username');
    define('DATABASE_PASSWORD', 'remote_password');
    define('DATABASE_TABLE', 'users');
}
/*
 * End of Defining Constants
 */

function read($username, $password) {
    /*
     * I use PDO and I recommend it over mysqli for I find it easier to work with, gives you more database options
     * other than MySQL and you can use named prepared statements instead of the silly ? marks.
     */
    $db_options = array(
        /* important! use actual prepared statements (default: emulate prepared statements) */
        PDO::ATTR_EMULATE_PREPARES => false
        /* throw exceptions on errors (default: stay silent) */
        , PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        /* fetch associative arrays (default: mixed arrays)    */
        , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    );
    $pdo = new PDO('mysql:host=' . DATABASE_HOST . ';dbname=' . DATABASE_NAME . ';charset=utf8', DATABASE_USERNAME, DATABASE_PASSWORD, $db_options);
    /* Setup the Query for reading in login data from database table */
    $query = 'SELECT id, username, password, full_name, email, security_level, private  FROM users WHERE username=:username';


    $stmt = $pdo->prepare($query); // Prepare the query:
    $stmt->execute([':username' => $username]); // Execute the query with the supplied user's parameter(s):

    $stmt->setFetchMode(PDO::FETCH_OBJ); // If you want to use an array then use FETCH_ASSOC:
    $user = $stmt->fetch(); // Fetch the appropiate record:
    
    /*
     * If username isn't in the database table return false.
     */
    if (!$user) {
        return FALSE;
    }
    /*
     * If password matches database table match send back true otherwise send back false.
     * Check out http://php.net/manual/en/function.password-hash.php 
     * and 
     * http://php.net/manual/en/function.password-verify.php for better password management.
     */
    if (password_verify($password, $user->password)) {
        return \TRUE;
    } else {
        return \FALSE;
    }
}

/*
 * This is just an example of how you might grab the user's input.
 */
if (isset($submit) && $submit === 'login') {
    $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_FULL_SPECIAL_CHARS);

    $result = read($username, $password);
    if ($result) {
        after_successful_login();
    }
}

Notice there’s a column called security_level this is where I put my administration access levels of my website at. I also left out sessions of the variables coming in from the database table. The reason I did this is people have different ways of handling security and I didn’t get want to get bogged down debating security with other php gurus.

2 Likes

What’s the point in writing two code blocks that are doing exactly the same? Isset version works for 7+, so it’s all he needs. Sometimes i find your ideas really strange. All right, you are obsessed with supporting PHP versions that are 10+ years old and even not supported by the PHP community anymore. But this code snippet adds no backward compatibility whatsoever. It just bloats the code.

On a side note, version_compare(). But again, it’s just pointless here as well.

Besides, I am afraid that your query won’t give the OP what they need.

Anyone can login anywhere for starter. Even without a password at all, thanks to blatant SQL injection in this code. You should never put a variable directly to the query, but using parameters

2 Likes

It wouldn’t be too difficult to get all the passwords either, given they are stored un-hashed in a database prone to injection.

1 Like

It’s hard to work with such a database where credentials are stored in the same table with the actual data. But either way you should treat your table as two separate tables - one with users and one with profiles. thus first check the credentials and then select the actual data (if needed).
So the code (with PDO and password hashing) would be

if(!isset($_POST['username'], $_POST['password'], $_POST['txtbranch'])
{
    die ("Please fill all fields");
} 
$adminName = 'ADMIN';

$stmt = $pdo->prepare('SELECT * FROM sysfile WHERE username = ?');
$stmt->execute([$_POST['username']]);
$file = $stmt->fetch();

if (!$file || !password_verify($_POST['password'], $file['password'])
{
    die("Bad credentials");
}
if ($_POST['txtbranch'] != $file['txtbranch'])
{
    if ($_POST['username'] === $adminName)
    {
        $stmt = $pdo->prepare('SELECT * FROM sysfile WHERE txtbranch = ?');
        $stmt->execute([$_POST['txtbranch']]);
        $file = $stmt->fetch();
    } else {
        die ("You don't have access to this branch");
    }
}
// show branch
1 Like

I wrote the first code block because it is the method I prefer then realised it could possibly fail and decided to add the second verbose code block.

I like the version_compare() function and no doubt there are many other methods to achieve the same result.

Without knowing the branched field contents it is difficult to supply an exact solution.

I already solve my problem and this is my final code.

if($_POST['SUBMIT']=='Sign In')
{
	if($_POST['username'] && $_POST['password'] &&  $_POST['txtbranch']) 
	{	
		$username  = $_POST['username'];
		$password  = $_POST['password'];
		$txtbranch  = $_POST['txtbranch'];

		$query_callbranch=mysqli_query("SELECT * FROM sysfile WHERE USERNAME='$username' ")or die(mysql_error());
		while($rowcallbranch=mysqli_fetch_array($query_callbranch))
		{
			$pin = $rowcallbranch['pin'];

			if($pin == '9' && $username == 'admin')
			{
			    $query = mysqli_query("select * from sysfile where username='".$username."' and password='".$password."' limit 1");
				 
    			$count_user = mysqli_num_rows($query);
    			if($count_user==1)
				{
    				$row = mysqli_fetch_array($query);
    					
    				$_SESSION['userid']       = $row['userid'];
    				$_SESSION['username'] = $row['username'];
    				$_SESSION['pin']            = $row['pin'];
    				$_SESSION['branchid']   = $_POST['txtbranch'];
    				header("location:dashboard.php?success=1");
    			}else{
    				$error = 'Incorrect Username dan Password.';	
    			}
			}
				
			if($pin == '0')
			{
			    $query = mysqli_query("select * from sysfile where username='".$username."' and password='".$hash_pass."' and branchid='".$txtbranch."' limit 1");
				 
    			$count_user = mysqli_num_rows($query);
    			if($count_user==1)
				{
    				$row = mysqli_fetch_array($query);
    					
    				$_SESSION['userid']       = $row['userid'];
    				$_SESSION['username'] = $row['username'];
    				$_SESSION['pin']            = $row['pin'];
    				$_SESSION['branchid']   = $_POST['txtbranch'];
    				header("location:dashboard.php?success=1");
    			}else{
    					$error = 'Incorrect Username, Password and Branch.';	
				}
			}				
		}
	}
}

Glad you have found a solution @user9791 and thanks for letting us know.

I am horrified to see that you have reverted to mysql* functions when you were previously using mysqli*. The mysql* interface has been deprecated for many years now and has been removed completely from PHP7.

Oh sorry about that :sweat_smile: I will edit my answer again.

I doubt that sharing this code was a such good idea, because, as it was previously pointed out, this code freely lets anyone to any branch, and even let any willing person to collect all the passwords.

Besides, this code is logically incorrect. For the admin, it selects just the first branch in the table all the time, no matter what branch was actually selected.

3 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.