Remember me
This commit is contained in:
parent
eb93088f87
commit
e8023c308f
|
@ -20,6 +20,9 @@ function checkLogin($args)
|
|||
}
|
||||
|
||||
if ($Login->verifyUser($_POST['username'], $_POST['password'])) {
|
||||
if (isset($_POST['remember'])) {
|
||||
$Login->setRememberMe($_POST['username']);
|
||||
}
|
||||
// Renew the token. This token will be the same inside the session for multiple forms.
|
||||
$Security->generateTokenCSRF();
|
||||
Redirect::page('dashboard');
|
||||
|
@ -35,16 +38,45 @@ function checkLogin($args)
|
|||
return false;
|
||||
}
|
||||
|
||||
function checkRememberMe()
|
||||
{
|
||||
global $Security;
|
||||
global $Login;
|
||||
|
||||
if ($Security->isBlocked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Cookie::isset(REMEMBER_COOKIE_USERNAME) || !Cookie::isset(REMEMBER_COOKIE_TOKEN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$username = Cookie::get(REMEMBER_COOKIE_USERNAME);
|
||||
$token = Cookie::get(REMEMBER_COOKIE_TOKEN);
|
||||
|
||||
if ($Login->verifyUserByRemember($username, $token)) {
|
||||
$Security->generateTokenCSRF();
|
||||
Redirect::page('dashboard');
|
||||
return true;
|
||||
}
|
||||
|
||||
$Security->addToBlacklist();
|
||||
return false;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Main before POST
|
||||
// ============================================================================
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD']!=='POST') {
|
||||
checkRememberMe();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// POST Method
|
||||
// ============================================================================
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD']=='POST')
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD']=='POST') {
|
||||
checkLogin($_POST);
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,11 @@ define('CLI_STATUS', 'published');
|
|||
// Cli mode, username for new pages
|
||||
define('CLI_USERNAME', 'admin');
|
||||
|
||||
// Remember me
|
||||
define('REMEMBER_COOKIE_USERNAME', 'BLUDITREMEMBERUSERNAME');
|
||||
define('REMEMBER_COOKIE_TOKEN', 'BLUDITREMEMBERTOKEN');
|
||||
define('REMEMBER_COOKIE_EXPIRE_IN_DAYS', 30);
|
||||
|
||||
// Filename
|
||||
define('FILENAME', 'index.txt');
|
||||
|
||||
|
|
|
@ -11,8 +11,7 @@ class dbUsers extends dbJSON
|
|||
'salt'=> array('inFile'=>false, 'value'=>'!Pink Floyd!Welcome to the machine!'),
|
||||
'email'=> array('inFile'=>false, 'value'=>''),
|
||||
'registered'=> array('inFile'=>false, 'value'=>'1985-03-15 10:00'),
|
||||
'tokenEmail'=> array('inFile'=>false, 'value'=>''),
|
||||
'tokenEmailTTL'=> array('inFile'=>false, 'value'=>'2009-03-15 14:00'),
|
||||
'tokenRemember'=> array('inFile'=>false, 'value'=>''),
|
||||
'tokenAuth'=> array('inFile'=>false, 'value'=>''),
|
||||
'tokenAuthTTL'=> array('inFile'=>false, 'value'=>'2009-03-15 14:00'),
|
||||
'twitter'=> array('inFile'=>false, 'value'=>''),
|
||||
|
@ -119,7 +118,7 @@ class dbUsers extends dbJSON
|
|||
return md5( uniqid().time().DOMAIN );
|
||||
}
|
||||
|
||||
public function generateEmailToken()
|
||||
public function generateRememberToken()
|
||||
{
|
||||
return $this->generateAuthToken();
|
||||
}
|
||||
|
@ -134,6 +133,13 @@ class dbUsers extends dbJSON
|
|||
return sha1($password.$salt);
|
||||
}
|
||||
|
||||
public function setRememberToken($username, $token)
|
||||
{
|
||||
$args['username'] = $username;
|
||||
$args['tokenRemember'] = $token;
|
||||
return $this->set($args);
|
||||
}
|
||||
|
||||
public function setPassword($username, $password)
|
||||
{
|
||||
$salt = $this->generateSalt();
|
||||
|
@ -170,18 +176,25 @@ class dbUsers extends dbJSON
|
|||
return false;
|
||||
}
|
||||
|
||||
public function setTokenEmail($username)
|
||||
// Returns the username with the remember token assigned, FALSE otherwise
|
||||
public function getByRememberToken($token)
|
||||
{
|
||||
// Random hash
|
||||
$token = $this->generateEmailToken();
|
||||
$this->db[$username]['tokenEmail'] = $token;
|
||||
foreach ($this->db as $username=>$fields) {
|
||||
if ($fields['tokenRemember']==$token) {
|
||||
return $username;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Token time to live, defined by TOKEN_EMAIL_TTL
|
||||
$this->db[$username]['tokenEmailTTL'] = Date::currentOffset(DB_DATE_FORMAT, TOKEN_EMAIL_TTL);
|
||||
|
||||
// Save the database
|
||||
$this->save();
|
||||
return $token;
|
||||
// This function clean all tokens for Remember me
|
||||
// This function is used when some hacker try to use an invalid remember token
|
||||
public function invalidateAllRememberTokens()
|
||||
{
|
||||
foreach ($this->db as $username=>$values) {
|
||||
$this->db[$username]['tokenRemember'] = '';
|
||||
}
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
// Returns array with the username databases filtered by username, FALSE otherwise
|
||||
|
|
|
@ -2,24 +2,28 @@
|
|||
|
||||
class Cookie {
|
||||
|
||||
public static function get($name)
|
||||
public static function get($key)
|
||||
{
|
||||
if(isset($_COOKIE[$name]))
|
||||
{
|
||||
return($_COOKIE[$name]);
|
||||
if (isset($_COOKIE[$key])) {
|
||||
return $_COOKIE[$name];
|
||||
}
|
||||
|
||||
return(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function add($name, $value, $expire = 525600)
|
||||
public static function set($key, $value, $daysToExpire=30)
|
||||
{
|
||||
setcookie($name, $value, time() + ($expire * 60));
|
||||
// The time the cookie expires.
|
||||
// This is a Unix timestamp so is in number of seconds since the epoch.
|
||||
// In other words, you'll most likely set this with the time() function plus the number of seconds before you want it to expire.
|
||||
// Or you might use mktime(). time()+60*60*24*30 will set the cookie to expire in 30 days.
|
||||
// If set to 0, or omitted, the cookie will expire at the end of the session (when the browser closes).
|
||||
$expire = time()+60*60*24*$daysToExpire;
|
||||
setcookie($key, $value, $expire);
|
||||
}
|
||||
|
||||
public static function isSet($name)
|
||||
public static function isset($key)
|
||||
{
|
||||
return(isset($_COOKIE[$name]));
|
||||
return isset($_COOKIE[$key]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -9,11 +9,13 @@ class Login {
|
|||
$this->dbUsers = $dbUsers;
|
||||
}
|
||||
|
||||
// Returns the username of the user logged
|
||||
public function username()
|
||||
{
|
||||
return Session::get('username');
|
||||
}
|
||||
|
||||
// Returns the role of the user logged
|
||||
public function role()
|
||||
{
|
||||
return Session::get('role');
|
||||
|
@ -26,9 +28,8 @@ class Login {
|
|||
$username = Session::get('username');
|
||||
if (!empty($username)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Log::set(__METHOD__.LOG_SEP.'Session username empty, destroy the session.');
|
||||
} else {
|
||||
Log::set(__METHOD__.LOG_SEP.'Session username empty, destroying the session.');
|
||||
Session::destroy();
|
||||
return false;
|
||||
}
|
||||
|
@ -49,6 +50,19 @@ class Login {
|
|||
Log::set(__METHOD__.LOG_SEP.'User logged, fingerprint: '.$this->fingerPrint());
|
||||
}
|
||||
|
||||
public function setRememberMe($username)
|
||||
{
|
||||
$username = Sanitize::html($username);
|
||||
|
||||
// Set the token on the users database
|
||||
$token = $this->dbUsers->generateRememberToken();
|
||||
$this->dbUsers->setRememberToken($username, $token);
|
||||
|
||||
// Set the token on the cookies
|
||||
Cookie::set(REMEMBER_COOKIE_USERNAME, $username, REMEMBER_COOKIE_EXPIRE_IN_DAYS);
|
||||
Cookie::set(REMEMBER_COOKIE_TOKEN, $token, REMEMBER_COOKIE_EXPIRE_IN_DAYS);
|
||||
}
|
||||
|
||||
// Check if the username and the password are valid
|
||||
// Returns TRUE if valid and set the session
|
||||
// Returns FALSE for invalid username or password
|
||||
|
@ -71,7 +85,7 @@ class Login {
|
|||
}
|
||||
|
||||
$user = $this->dbUsers->getDB($username);
|
||||
if($user==false) {
|
||||
if ($user==false) {
|
||||
Log::set(__METHOD__.LOG_SEP.'Username does not exist: '.$username);
|
||||
return false;
|
||||
}
|
||||
|
@ -82,65 +96,46 @@ class Login {
|
|||
Log::set(__METHOD__.LOG_SEP.'User logged succeeded by username and password - Username: '.$username);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Log::set(__METHOD__.LOG_SEP.'Password incorrect.');
|
||||
}
|
||||
|
||||
Log::set(__METHOD__.LOG_SEP.'Password incorrect.');
|
||||
return false;
|
||||
}
|
||||
|
||||
public function verifyUserByToken($username, $token)
|
||||
// Verified Remember Token
|
||||
// If valid log in the user
|
||||
// If not valid invalidate all remember me tokens
|
||||
public function verifyUserByRemember($username, $token)
|
||||
{
|
||||
$username = Sanitize::html($username);
|
||||
$token = Sanitize::html($token);
|
||||
$username = Sanitize::html($username);
|
||||
$token = Sanitize::html($token);
|
||||
|
||||
$username = trim($username);
|
||||
$token = trim($token);
|
||||
$username = trim($username);
|
||||
$token = trim($token);
|
||||
|
||||
if(empty($username) || empty($token)) {
|
||||
Log::set(__METHOD__.LOG_SEP.'Username or Token-email empty. Username: '.$username.' - Token-email: '.$token);
|
||||
if (empty($username) || empty($token)) {
|
||||
$this->dbUsers->invalidateAllRememberTokens();
|
||||
Log::set(__METHOD__.LOG_SEP.'Username or Token empty. Username: '.$username.' - Token: '.$token);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($username !== $this->getByRememberToken($token)) {
|
||||
$this->dbUsers->invalidateAllRememberTokens();
|
||||
Log::set(__METHOD__.LOG_SEP.'The user has different token or the token doesnt exist.');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate user and login
|
||||
$user = $this->dbUsers->getDb($username);
|
||||
if($user==false) {
|
||||
Log::set(__METHOD__.LOG_SEP.'Username does not exist: '.$username);
|
||||
return false;
|
||||
}
|
||||
|
||||
$currentTime = Date::current(DB_DATE_FORMAT);
|
||||
if($user['tokenEmailTTL']<$currentTime) {
|
||||
Log::set(__METHOD__.LOG_SEP.'Token-email expired: '.$username);
|
||||
return false;
|
||||
}
|
||||
|
||||
if($token === $user['tokenEmail'])
|
||||
{
|
||||
// Set the user loggued.
|
||||
$this->setLogin($username, $user['role']);
|
||||
|
||||
// Invalidate the current token.
|
||||
$this->dbUsers->setTokenEmail($username);
|
||||
|
||||
Log::set(__METHOD__.LOG_SEP.'User logged succeeded by Token-email - Username: '.$username);
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Log::set(__METHOD__.LOG_SEP.'Token-email incorrect.');
|
||||
}
|
||||
|
||||
return false;
|
||||
$this->setLogin($username, $user['role']);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function fingerPrint()
|
||||
{
|
||||
// User agent
|
||||
$agent = getenv('HTTP_USER_AGENT');
|
||||
if (empty($agent)) {
|
||||
$agent = 'Bludit/2.0 (Mr Nibbler Protocol)';
|
||||
}
|
||||
|
||||
return sha1($agent);
|
||||
}
|
||||
|
||||
|
@ -148,5 +143,4 @@ class Login {
|
|||
{
|
||||
return Session::destroy();
|
||||
}
|
||||
|
||||
}
|
|
@ -37,7 +37,7 @@ h2 {
|
|||
}
|
||||
/* PAGES */
|
||||
|
||||
article.page:not(:last-child) {
|
||||
article.page {
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue