Admin Login

Hello, I’m having a small issue when an “Admin” logs in, it doesn’t redirect to the “admin” page. Im pretty sure it’s just something in the script, but i’m not sure what.

<?php

class Login extends MainController{
	function __construct(){
			parent::__construct();
			$this->view->url	=	$this->config->url;
			$this->view->ID 	  = get_class($this);
			$this->view->Title = "";
			
			// Data Login
			$userName	=	isset($_POST['username']) ? $_POST['username'] : '';
			$passWord   =   isset($_POST['password']) ? $_POST['password'] : '';

			$sql = "SELECT * FROM users WHERE username = :username AND password = MD5(:password)";
			$arr = array(":username" => $userName,":password" => $passWord);
			$ctr = $this->database->DBCtr($sql,$arr);
			
			if($ctr > 0){
				$usr = $this->database->DBQry($sql,$arr);
				$_SESSION['user'] = $usr[0]['username'];
				$role = $usr[0]['role'];
				header("location:Index");
			}elseif($role == 'admin'){
				header("location:Admin");
			}else{
				header("location:NotAuthorize");
			}
		
	}
	
}
?>

Thats the script for logging in, if any more scripts are needed please let me know.

Looks like you’re doing an automatic redirect to index if ctr is greater than zero before any checks for admin. I would change it to if greater than zero, do checks (pass, not authorized) and if NOT greater than zero send to index.

if($ctr > 0){
	$usr = $this->database->DBQry($sql,$arr);
	$_SESSION['user'] = $usr[0]['username'];
	$role = $usr[0]['role'];
	if($role == 'admin'){
		header("location:Admin");
		exit;
	}else{
		header("location:NotAuthorize");
		exit;
	}
}else{
	header("location:Index");
	exit;
}

You might also set the ROLE to session.

if($ctr > 0){
	$usr = $this->database->DBQry($sql,$arr);
	$_SESSION['user'] = $usr[0]['username'];
    $_SESSION['role'] = $usr[0]['role'];
	$role = $usr[0]['role'];
	if($role == 'admin'){
		header("location:Admin");
		exit;
	}else{
		header("location:NotAuthorize");
		exit;
	}
}else{
	header("location:Index");
	exit;
}

Then add a little check on your admin pages to make sure user is authorized.

//check authorization
if (!isset($_SESSION['user']) || !isset($_SESSION['role'])) {	
	session_destroy();
	header("location:Index");
	exit;
}elseif($_SESSION['role']!="admin"){	
	session_destroy();
	header("location:Index");
	exit;
}

Thank you so much, it works perfectly!

I’m sure the topic will come up regarding MD5 and salting your password and even mentioning it here can open a huge can of worms as to the best way to do things. I will offer a suggestion and you can take it for what it is. I would add a field to your users table called salt. When a person logs in, you query using only the user name as the query condition, grab the salt and password and any other info you wish. Then add the salt to the POSTED password and get a hashed password, which would then be compared to the stored password for match. Not sure If I’ve got everything straight in this example but it would go something like this.

$sql = "SELECT * FROM users WHERE username = :username";
$arr = array(":username" => $userName);
$ctr = $this->database->DBCtr($sql,$arr);
if($ctr > 0){
	$usr = $this->database->DBQry($sql,$arr);
	$salt = $usr[0]['salt'];
	$pass = $usr[0]['password'];
	$user = $usr[0]['username'];
	$role = $usr[0]['role'];
	/*
	Here we take the POSTED password variable, add our salt value (stored in DB)
	to get our hashed password.  This must match our password for this user.
	*/
	$hashedpass = hash('sha256', $salt.$passWord);
	//Check if values match
	if ($hashedpass==$pass){
	    if($role == 'admin'){
		    $_SESSION['user'] = $user;
		    $_SESSION['role'] = $role;
			unset($_POST);
			unset($salt);
			unset($pass);
			unset($role);
	        header("location:Admin");
	        exit;
	    }else{
			unset($_POST);
			unset($salt);
			unset($pass);
			unset($role);
	        header("location:NotAuthorize");
	        exit;
	    }		
	}else{
		unset($_POST);
		unset($salt);
		unset($pass);
		unset($role);
	    header("location:Index");
	    exit;
	}
}else{
    header("location:Index");
    exit;
}

This would also mean that you’d need to create SALT when the person registers for an account and store this in the users table. Add something like this to the registration section.


function createSalt() {
	$string = md5(uniqid(rand(), true));
	return substr($string, 0, 13);
}

$salt = createsalt();
$password = trim($_POST['password']);
$hash = hash('sha256', $salt.$password);

You would then use $hash as the value you save as their password and $salt would be salt.

Don’t use MD5. It’s fairly easy to reverse it these days.

Use this function and this hashing algorithm instead:

$hashedvalue = hash('sha512', $mydata);

It’s much more difficult to reverse the hash.

http://www.php.net/manual/en/function.hash.php

Or, even better, use BCrypt, as is encouraged in the new PHP5.5 password functions. In fact, you can add the PHP5.5 functions to PHP5.3 and PHP5.4 with this library: https://github.com/Antnee/phpPasswordHashingLib

Use a hash that is designed to store passwords at rest :wink: No need to store a separate salt, no need to specify the salt yourself either, and all the functions are compatible with the PHP5.5 syntax so if/when you upgrade to PHP5.5 your code will continue to work with native functions. Feel free to contribute and make the code better; it was quickly put together but does exactly what it says on the tin