This is a Login Authentication / Sign-up Models for my class project in PHP. I'd really appreciate criticisms and any suggestions to improve... security/code quality/...etc
Hashing.php
class Hashing{
public static function getHashedPassword($username, $password, $regTime){
//Prepending Username and Appending Registration time as Salts before hashing & storing the password
return password_hash($username.$password.$regTime, PASSWORD_DEFAULT);
}
public static function verifyHash($password, $hash){
return password_verify($password,$hash);
}
}
LoginService.php
require_once("UserInfo.php");
require_once("../../model/db/DbService.php");
include("../../model/login/Roles.php");
include("../../model/login/Hashing.php");
class LoginService{
private $dbConnection;
public static $USER_NOT_FOUND=-1;
public static $PASSWORD_MISMATCH=0;
public static $USER_FOUND=1;
//Retrieve a PDO Connection
function __construct(DbService $dbService){$this->dbConnection=$dbService->getDbConnection();}
public function verify($username, $password){
try{
/*Given a username and password,
We will query the Database to get the user with that username;
*/
$SQL="SELECT * FROM users WHERE username=:username";
$statement=$this->dbConnection->prepare($SQL);
$statement->bindParam(":username", $username);
$statement->execute();
// If no rows were returned, that means there exists no such user.
if ($statement->rowCount()==0) return LoginService::$USER_NOT_FOUND;
// If user exists, we construct a user object.
$user=$statement->fetch(PDO::FETCH_OBJ);
// Verify
if(Hashing::verifyHash($username.$password.$user->reg_time, $user->password)) return LoginService::$USER_FOUND;
// If we failed to verify
return LoginService::$PASSWORD_MISMATCH;
}catch(Exception $e){
// In any other event, throw an exception
throw $e;
}
}
}
SignUpService.php
require_once("UserInfo.php");
require_once("../../model/db/DbService.php");
include("../../model/login/Roles.php");
include("../../model/login/Hashing.php");
class SignUpService{
private $userInfo;
private $dbConnection;
// On init, we recieve a UserInfo Object and store it.
// Next we retrieve a PDO Connection from DbService().getDbConnection.
function __construct(DbService $dbService){$this->dbConnection=$dbService->getDbConnection();}
// We try to store the new user in the database,
// Throws PDO Exception
public function register(UserInfo $userInfo){
$this->userInfo=$userInfo;
try{
$this->execute();
return true;
}catch(Exception $e){throw $e;}
}
private function execute(){
$SQL="INSERT INTO users (username,password,f_name, l_name, email, phone, reg_time, role) VALUES (:username, :password, :f_name, :l_name, :email, :phone, :reg_time, :role)";
$statement=$this->dbConnection->prepare($SQL);
$statement->bindParam(":username", $this->userInfo->getUsername());
$statement->bindParam(":password", $this->getHashedPassword(new Hashing()));
$statement->bindParam(":f_name", $this->userInfo->getFName());
$statement->bindParam(":l_name", $this->userInfo->getLName());
$statement->bindParam(":email" , $this->userInfo->getEmail());
$statement->bindParam(":phone", $this->userInfo->getPhone());
$statement->bindParam(":reg_time", $this->userInfo->getRegTime());
$statement->bindParam(":role", Roles::$STUDENT);
$statement->execute();
}
// Salt & Hash
private function getHashedPassword(){
$username=$this->userInfo->getUsername();
$password=$this->userInfo->getPassword();
$regTime=$this->userInfo->getRegTime();
return Hashing::getHashedPassword($username, $password,$regTime);
}
}
DbService.php
require_once("DbLoginConsts.php");
// Whenever a PDO connection is required, we aqquire the connection by calling new DbSerive()->getDbConnection();
// This reassures that we are not creating multiple open connections.
// Use closeDbConnection() to deallocate resources.
class DbService{
private $dbConnection=null;
public function getDbConnection(){
//Retreiving Settings from Configs/mysql.xml file
$dbLoginInfo=new DbLoginConsts();
if (is_null($this->dbConnection)){
$this->dbConnection=new PDO($dbLoginInfo->getUrl(), $dbLoginInfo->getUsername(), $dbLoginInfo->getPassword());
// Allowing PDO to throw Exceptions
$this->dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
//Returning an Instance of a PDO Object.
return $this->dbConnection;
}
public function closeDbConnection(){
$this->dbConnection=null;
}
}