mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-05-22 05:15:29 +09:00
Implement autologin in the Session class
This commit is contained in:
parent
d36263f539
commit
2af90c8e1d
3 changed files with 117 additions and 88 deletions
|
|
@ -362,11 +362,6 @@ class Context
|
||||||
{
|
{
|
||||||
$oMemberController->setSessionInfo();
|
$oMemberController->setSessionInfo();
|
||||||
}
|
}
|
||||||
// check auto sign-in
|
|
||||||
elseif($_COOKIE['xeak'])
|
|
||||||
{
|
|
||||||
$oMemberController->doAutologin();
|
|
||||||
}
|
|
||||||
|
|
||||||
self::set('is_logged', $oMemberModel->isLogged());
|
self::set('is_logged', $oMemberModel->isLogged());
|
||||||
self::set('logged_info', $oMemberModel->getLoggedInfo());
|
self::set('logged_info', $oMemberModel->getLoggedInfo());
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ class Session
|
||||||
self::$_started = true;
|
self::$_started = true;
|
||||||
|
|
||||||
// Fetch session keys.
|
// Fetch session keys.
|
||||||
list($key1, $key2) = self::_getKeys();
|
list($key1, $key2, $autologin_key) = self::_getKeys();
|
||||||
$must_create = $must_refresh = $must_resend_keys = false;
|
$must_create = $must_refresh = $must_resend_keys = false;
|
||||||
|
|
||||||
// Validate the HTTP key.
|
// Validate the HTTP key.
|
||||||
|
|
@ -122,8 +122,11 @@ class Session
|
||||||
}
|
}
|
||||||
elseif (!$relax_key_checks)
|
elseif (!$relax_key_checks)
|
||||||
{
|
{
|
||||||
|
// Hacked session! Destroy everything.
|
||||||
$_SESSION = array();
|
$_SESSION = array();
|
||||||
$must_create = true;
|
$must_create = true;
|
||||||
|
self::setAutologinKeys(null, null);
|
||||||
|
$autologin_key = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -148,8 +151,11 @@ class Session
|
||||||
}
|
}
|
||||||
elseif (!$relax_key_checks)
|
elseif (!$relax_key_checks)
|
||||||
{
|
{
|
||||||
|
// Hacked session! Destroy everything.
|
||||||
$_SESSION = array();
|
$_SESSION = array();
|
||||||
$must_create = true;
|
$must_create = true;
|
||||||
|
self::setAutologinKeys(null, null);
|
||||||
|
$autologin_key = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,7 +172,7 @@ class Session
|
||||||
// Create or refresh the session if needed.
|
// Create or refresh the session if needed.
|
||||||
if ($must_create)
|
if ($must_create)
|
||||||
{
|
{
|
||||||
return self::create();
|
return self::create($autologin_key);
|
||||||
}
|
}
|
||||||
elseif ($must_refresh)
|
elseif ($must_refresh)
|
||||||
{
|
{
|
||||||
|
|
@ -318,9 +324,10 @@ class Session
|
||||||
*
|
*
|
||||||
* This method is called automatically by start() when needed.
|
* This method is called automatically by start() when needed.
|
||||||
*
|
*
|
||||||
|
* @param string $autologin_key (optional)
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function create()
|
public static function create($autologin_key = null)
|
||||||
{
|
{
|
||||||
// Ensure backward compatibility with XE session.
|
// Ensure backward compatibility with XE session.
|
||||||
$member_srl = $_SESSION['member_srl'] ?: false;
|
$member_srl = $_SESSION['member_srl'] ?: false;
|
||||||
|
|
@ -329,7 +336,7 @@ class Session
|
||||||
|
|
||||||
// Create the data structure for a new Rhymix session.
|
// Create the data structure for a new Rhymix session.
|
||||||
$_SESSION['RHYMIX'] = array();
|
$_SESSION['RHYMIX'] = array();
|
||||||
$_SESSION['RHYMIX']['login'] = $_SESSION['member_srl'] = $member_srl;
|
$_SESSION['RHYMIX']['login'] = $_SESSION['member_srl'] = intval($member_srl);
|
||||||
$_SESSION['RHYMIX']['ipaddress'] = $_SESSION['ipaddress'] = \RX_CLIENT_IP;
|
$_SESSION['RHYMIX']['ipaddress'] = $_SESSION['ipaddress'] = \RX_CLIENT_IP;
|
||||||
$_SESSION['RHYMIX']['useragent'] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
|
$_SESSION['RHYMIX']['useragent'] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
|
||||||
$_SESSION['RHYMIX']['language'] = \Context::getLangType();
|
$_SESSION['RHYMIX']['language'] = \Context::getLangType();
|
||||||
|
|
@ -338,7 +345,25 @@ class Session
|
||||||
$_SESSION['RHYMIX']['tokens'] = array();
|
$_SESSION['RHYMIX']['tokens'] = array();
|
||||||
|
|
||||||
// Pass control to refresh() to generate security keys.
|
// Pass control to refresh() to generate security keys.
|
||||||
return self::refresh();
|
$result = self::refresh();
|
||||||
|
|
||||||
|
// Try autologin.
|
||||||
|
if (!$member_srl && $autologin_key)
|
||||||
|
{
|
||||||
|
$member_srl = getController('member')->doAutologin($autologin_key);
|
||||||
|
if ($member_srl)
|
||||||
|
{
|
||||||
|
$_SESSION['RHYMIX']['login'] = $_SESSION['member_srl'] = intval($member_srl);
|
||||||
|
$_SESSION['is_logged'] = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self::setAutologinKeys(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the result obtained above.
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -416,6 +441,7 @@ class Session
|
||||||
self::$_started = false;
|
self::$_started = false;
|
||||||
self::$_member_info = false;
|
self::$_member_info = false;
|
||||||
self::_setKeys();
|
self::_setKeys();
|
||||||
|
self::setAutologinKeys(null, null);
|
||||||
@session_destroy();
|
@session_destroy();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -761,7 +787,7 @@ class Session
|
||||||
protected static function _getKeys()
|
protected static function _getKeys()
|
||||||
{
|
{
|
||||||
// Initialize keys.
|
// Initialize keys.
|
||||||
$key1 = $key2 = null;
|
$key1 = $key2 = $key3 = null;
|
||||||
|
|
||||||
// Fetch and validate the HTTP-only key.
|
// Fetch and validate the HTTP-only key.
|
||||||
if (isset($_COOKIE['rx_sesskey1']) && ctype_alnum($_COOKIE['rx_sesskey1']) && strlen($_COOKIE['rx_sesskey1']) === 24)
|
if (isset($_COOKIE['rx_sesskey1']) && ctype_alnum($_COOKIE['rx_sesskey1']) && strlen($_COOKIE['rx_sesskey1']) === 24)
|
||||||
|
|
@ -775,7 +801,13 @@ class Session
|
||||||
$key2 = $_COOKIE['rx_sesskey2'];
|
$key2 = $_COOKIE['rx_sesskey2'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($key1, $key1 === null ? null : $key2);
|
// Fetch and validate the autologin key.
|
||||||
|
if (isset($_COOKIE['rx_autologin']) && ctype_alnum($_COOKIE['rx_autologin']) && strlen($_COOKIE['rx_autologin']) === 48)
|
||||||
|
{
|
||||||
|
$key3 = $_COOKIE['rx_autologin'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($key1, $key1 === null ? null : $key2, $key3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -810,4 +842,32 @@ class Session
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set autologin key.
|
||||||
|
*
|
||||||
|
* @param string $autologin_key
|
||||||
|
* @param string $security_key
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function setAutologinKeys($autologin_key = null, $security_key = null)
|
||||||
|
{
|
||||||
|
// Get session parameters.
|
||||||
|
list($lifetime, $refresh_interval, $domain, $path) = self::_getParams();
|
||||||
|
$lifetime = time() + (86400 * 365);
|
||||||
|
|
||||||
|
// Set or destroy the HTTP-only key.
|
||||||
|
if ($autologin_key && $security_key)
|
||||||
|
{
|
||||||
|
setcookie('rx_autologin', $autologin_key . $security_key, $lifetime, $path, $domain, false, true);
|
||||||
|
$_COOKIE['rx_autologin'] = $autologin_key . $security_key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setcookie('rx_autologin', 'deleted', time() - 86400, $path, $domain, false, true);
|
||||||
|
unset($_COOKIE['rx_autologin']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1623,82 +1623,56 @@ class memberController extends member
|
||||||
/**
|
/**
|
||||||
* Auto-login
|
* Auto-login
|
||||||
*
|
*
|
||||||
* @return void
|
* @param string $autologin_key
|
||||||
|
* @return int|false
|
||||||
*/
|
*/
|
||||||
function doAutologin()
|
function doAutologin($autologin_key = null)
|
||||||
{
|
{
|
||||||
// Get a key value of auto log-in
|
// Validate the key.
|
||||||
$args = new stdClass;
|
if (strlen($autologin_key) == 48)
|
||||||
$args->autologin_key = $_COOKIE['xeak'];
|
|
||||||
// Get information of the key
|
|
||||||
$output = executeQuery('member.getAutologin', $args);
|
|
||||||
// If no information exists, delete a cookie
|
|
||||||
if(!$output->toBool() || !$output->data)
|
|
||||||
{
|
{
|
||||||
setCookie('xeak',null,$_SERVER['REQUEST_TIME']+60*60*24*365, '/');
|
$security_key = substr($autologin_key, 24, 24);
|
||||||
return;
|
$autologin_key = substr($autologin_key, 0, 24);
|
||||||
}
|
|
||||||
|
|
||||||
$oMemberModel = getModel('member');
|
|
||||||
$config = $oMemberModel->getMemberConfig();
|
|
||||||
|
|
||||||
$user_id = ($config->identifier == 'user_id') ? $output->data->user_id : $output->data->email_address;
|
|
||||||
$password = $output->data->password;
|
|
||||||
|
|
||||||
if(!$user_id || !$password)
|
|
||||||
{
|
|
||||||
setCookie('xeak',null,$_SERVER['REQUEST_TIME']+60*60*24*365, '/');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$do_auto_login = false;
|
|
||||||
|
|
||||||
// Compare key values based on the information
|
|
||||||
$check_key = strtolower($user_id).$password.$_SERVER['HTTP_USER_AGENT'];
|
|
||||||
$check_key = substr(hash_hmac('sha256', $check_key, substr($args->autologin_key, 0, 32)), 0, 32);
|
|
||||||
|
|
||||||
if($check_key === substr($args->autologin_key, 32))
|
|
||||||
{
|
|
||||||
// Check change_password_date
|
|
||||||
$oModuleModel = getModel('module');
|
|
||||||
$member_config = $oModuleModel->getModuleConfig('member');
|
|
||||||
$limit_date = $member_config->change_password_date;
|
|
||||||
|
|
||||||
// Check if change_password_date is set
|
|
||||||
if($limit_date > 0)
|
|
||||||
{
|
|
||||||
$oMemberModel = getModel('member');
|
|
||||||
$columnList = array('member_srl', 'change_password_date');
|
|
||||||
|
|
||||||
if($config->identifier == 'user_id')
|
|
||||||
{
|
|
||||||
$member_info = $oMemberModel->getMemberInfoByUserID($user_id, $columnList);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$member_info = $oMemberModel->getMemberInfoByEmailAddress($user_id, $columnList);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($member_info->change_password_date >= date('YmdHis', strtotime('-'.$limit_date.' day')) ){
|
|
||||||
$do_auto_login = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$do_auto_login = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if($do_auto_login)
|
|
||||||
{
|
|
||||||
$output = $this->doLogin($user_id);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
executeQuery('member.deleteAutologin', $args);
|
return false;
|
||||||
setCookie('xeak',null,$_SERVER['REQUEST_TIME']+60*60*24*365, '/');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch autologin information from DB.
|
||||||
|
$args = new stdClass;
|
||||||
|
$args->autologin_key = $autologin_key;
|
||||||
|
$output = executeQuery('member.getAutologin', $args);
|
||||||
|
if (!$output->toBool() || !$output->data)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (is_array($output->data))
|
||||||
|
{
|
||||||
|
$output->data = array_first($output->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the security key.
|
||||||
|
if ($output->data->security_key !== $security_key || !$output->data->member_srl)
|
||||||
|
{
|
||||||
|
$args = new stdClass;
|
||||||
|
$args->autologin_key = $autologin_key;
|
||||||
|
executeQuery('member.deleteAutologin', $args);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the security key.
|
||||||
|
$new_security_key = Rhymix\Framework\Security::getRandom(24, 'alnum');
|
||||||
|
$args = new stdClass;
|
||||||
|
$args->security_key = $new_security_key;
|
||||||
|
$update_output = executeQuery('member.updateAutologin', $args);
|
||||||
|
if ($update_output->toBool())
|
||||||
|
{
|
||||||
|
Rhymix\Framework\Session::setAutologinKeys($autologin_key, $new_security_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the member_srl.
|
||||||
|
return intval($output->data->member_srl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1860,16 +1834,16 @@ class memberController extends member
|
||||||
// When user checked to use auto-login
|
// When user checked to use auto-login
|
||||||
if($keep_signed)
|
if($keep_signed)
|
||||||
{
|
{
|
||||||
// Key generate for auto login
|
$random_key = Rhymix\Framework\Security::getRandom(48, 'alnum');
|
||||||
$random_key = Rhymix\Framework\Security::getRandom(32, 'hex');
|
|
||||||
$extra_key = strtolower($user_id).$this->memberInfo->password.$_SERVER['HTTP_USER_AGENT'];
|
|
||||||
$extra_key = substr(hash_hmac('sha256', $extra_key, $random_key), 0, 32);
|
|
||||||
$autologin_args = new stdClass;
|
$autologin_args = new stdClass;
|
||||||
$autologin_args->autologin_key = $random_key.$extra_key;
|
$autologin_args->autologin_key = substr($random_key, 0, 24);
|
||||||
|
$autologin_args->security_key = substr($random_key, 24, 24);
|
||||||
$autologin_args->member_srl = $this->memberInfo->member_srl;
|
$autologin_args->member_srl = $this->memberInfo->member_srl;
|
||||||
executeQuery('member.deleteAutologin', $autologin_args);
|
|
||||||
$autologin_output = executeQuery('member.insertAutologin', $autologin_args);
|
$autologin_output = executeQuery('member.insertAutologin', $autologin_args);
|
||||||
if($autologin_output->toBool()) setCookie('xeak',$autologin_args->autologin_key, $_SERVER['REQUEST_TIME']+31536000, '/');
|
if ($autologin_output->toBool())
|
||||||
|
{
|
||||||
|
Rhymix\Framework\Session::setAutologinKeys(substr($random_key, 0, 24), substr($random_key, 24, 24));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setSessionInfo();
|
$this->setSessionInfo();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue