Reputation: 47
I've been working on this authentication system for user login and would appreciate some feedback.
My idea is this. Use sessions and one additional cookie. Session cookie and additional cookie work together. In my Login class, after i check if the username and password are correct, i call sessionStart method and send user's id from database:
public function sessionStart($id) {
session_start();
$cookieName = "RagingBull";
$hash = $this->loginHash($id);
setcookie($cookieName, $hash);
}
In my sessionStart method, a loginHash method is called. loginHash method creates hash and links together session cookie and additional cookie.
public function loginHash($id) {
$timeStamp = time();
$randNumber = mt_rand(0, 1000);
$userId = $id;
$_SESSION['timeStamp'] = $timeStamp;
$_SESSION['randNumber'] = $randNumber;
$_SESSION['userId'] = $id;
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$salt = "On the Waterfront";
$ipFrag = substr($this->getUserIP(), 0, 5);
$forHash = $timeStamp.$salt.$userId.$ipFrag.$randNumber.$userAgent;
$hash = md5($forHash);
return $hash;
}
For creating a hash value, i use
I save some values in session cookie so that i can use them later when creating hash for comparison. After that, we go back to sessionStart method, and create additional cookie with returned hash value, and then user is logged in.
For authentication, i have Session class.
class Session {
public function __construct() {
session_start();
// checks to see if all the cookies are there
if(!isset($_SESSION['userId']) || !isset($_COOKIE['RagingBull'])) {
header("Location:http://localhost/login.php");
}
//create hash for comparison
$hash = $this->loginHash();
//if hashes are not the same, redirect
if(strcmp($hash, $_COOKIE['RagingBull']) !== 0) {
header("Location:http://localhost/login.php");
}
}
public function loginHash() {
$timeStamp = $_SESSION['timeStamp'];
$randNumber = $_SESSION['randNumber'];
$userId = $_SESSION['userId'];
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$salt = "On the Waterfront";
$ipFrag = substr($this->getUserIP(), 0, 5);
$forHash = $timeStamp.$salt.$userId.$ipFrag.$randNumber.$userAgent;
$hash = md5($forHash);
return $hash;
}
public function getUserIP() {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
}
To use it, i just create instance of Session class. Then, in constructor, after basic checking, there is creation of hash for comparison, i use the timeStamp, userId and randNumber from session cookie which i saved before, and combine them with user agent and ip fragment from user who requested page.
Upvotes: 0
Views: 84
Reputation: 34113
This code does a lot of pointless things insecurely.
mt_rand()
instead of random_int()
.md5($var)
instead of hash('sha256', $var)
md5($password)
instead of password_hash()
and password_verify()
If you're trying to do persistent authentication (i.e. "remember me" cookies), just implement that.
If you're trying to protect against session attacks, just use TLS (and ensure your session ID is generated from /dev/urandom
if you're still on PHP 5) and strict mode. Call session_regenerate_id(true)
whenever the user logs in or logs out. Done.
The hashing here adds no value, and you're using tools that were not meant for secure authentication.
Upvotes: 0