This seems to work for me, but I want to make it more secure. I want to see how far I can go without pre-built packages/bundles, so please don't suggest any.
How secure is this? What are some steps I can take to improve it?
In a controller:
public function loginUser($request, $response) {
if (Security::isUser()) { return $this->redirect('home'); }
$username = $request->getParam('username');
$password = $request->getParam('password');
$user = Security::authenticate($username, $password);
if ($user) {
Security::login($user->id);
return $this->redirect('home');
} else {
$this->flash->addMessage('error', 'Invalid username and/or password.');
return $this->redirect('login');
}
}
Here is part of the Security
class:
public static function hash($string) {
return password_hash($string, PASSWORD_DEFAULT);
}
public static function authenticate($username, $password) {
$user = User::where('username', $username)->orWhere('email', $username)->first();
if (password_verify($password, $user->password) && $user->banned === 0) { return $user; }
else { return false; }
}
public static function getUser() {
if (isset($_SESSION['uid'])) {
$user = User::where('id', $_SESSION['uid'])->first();
if ($user->banned === 1) { return false; }
else { return $user; }
} else { return false; }
}
public static function isUser() {
if (!self::getUser()) { return false; } else { return true; }
}
public static function isAdmin() {
$user = self::getUser();
if (!$user) { return false; }
else if ($user->role === 'admin') { return true; }
else { return false; }
}
public static function login($uid) {
session_regenerate_id();
$_SESSION['uid'] = $uid;
}
public static function logout() {
session_unset();
session_destroy();
}
Then, to secure something:
public function loginUser($request, $response) {
if (!Security::isUser()) { // or use ::isAdmin()
// deny access
}
// allow access
}
Csrf tokens are checked by Slim's Guard. This is all over https.