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?
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
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.
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
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
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.
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.