Keep previous autologin security key in database, in case the client STILL hasn't got the new cookie

This commit is contained in:
Kijin Sung 2023-08-04 02:21:01 +09:00
parent 348d1c4352
commit 555f5b6017
5 changed files with 37 additions and 10 deletions

View file

@ -158,6 +158,7 @@ class Member extends ModuleObject
// Check autologin table
if(!$oDB->isColumnExists("member_autologin", "security_key")) return true;
if(!$oDB->isColumnExists("member_autologin", "previous_key")) return true;
// Check scrap folder table
if(!$oDB->isColumnExists("member_scrap", "folder_srl")) return true;
@ -360,6 +361,10 @@ class Member extends ModuleObject
$oDB->dropTable('member_autologin');
$oDB->createTable($this->module_path . '/schemas/member_autologin.xml');
}
if(!$oDB->isColumnExists("member_autologin", "previous_key"))
{
$oDB->addColumn("member_autologin", "previous_key", "varchar", 80, null, false, "security_key");
}
// Check scrap folder table
if(!$oDB->isColumnExists("member_scrap", "folder_srl"))

View file

@ -2181,6 +2181,7 @@ class MemberController extends Member
// Fetch autologin information from DB.
$args = new stdClass;
$args->autologin_key = $autologin_key;
$args->page = 0;
$output = executeQuery('member.getAutologin', $args);
if (!$output->toBool() || !$output->data)
{
@ -2190,12 +2191,16 @@ class MemberController extends Member
{
$output->data = array_first($output->data);
}
if (!$output->data || !$output->data->member_srl)
{
return false;
}
// Hash the security key.
$valid_security_keys = array(base64_encode(hash_hmac('sha256', $security_key, $autologin_key, true)));
$hashed_security_key = base64_encode(hash_hmac('sha256', $security_key, $autologin_key, true));
// Check the security key.
if (!in_array($output->data->security_key, $valid_security_keys) || !$output->data->member_srl)
if ($hashed_security_key !== $output->data->security_key && $hashed_security_key !== $output->data->previous_key ?? '')
{
$args = new stdClass;
$args->autologin_key = $autologin_key;
@ -2203,15 +2208,29 @@ class MemberController extends Member
return false;
}
// Update the security key.
$new_security_key = Rhymix\Framework\Security::getRandom(24, 'alnum');
$args = new stdClass;
$args->autologin_key = $autologin_key;
$args->security_key = base64_encode(hash_hmac('sha256', $new_security_key, $autologin_key, true));
$update_output = executeQuery('member.updateAutologin', $args);
if ($update_output->toBool())
// If the current security key matches, generate a new key.
// If the previous key matches, don't update until the client has the current key.
// Resending the current key in this case will be handled by the Session class.
if ($hashed_security_key === $output->data->security_key)
{
Rhymix\Framework\Session::setAutologinKeys($autologin_key, $new_security_key);
$new_security_key = Rhymix\Framework\Security::getRandom(24, 'alnum');
$new_hash = base64_encode(hash_hmac('sha256', $new_security_key, $autologin_key, true));
$args = new stdClass;
$args->autologin_key = $autologin_key;
$args->security_key = $new_hash;
$args->previous_key = $output->data->security_key;
$update_output = executeQuery('member.updateAutologin', $args);
if ($update_output->toBool())
{
Rhymix\Framework\Session::setAutologinKeys($autologin_key, $new_security_key);
}
}
else
{
$args = new stdClass;
$args->autologin_key = $autologin_key;
$update_output = executeQuery('member.updateAutologin', $args);
}
// Update the last login time.

View file

@ -5,6 +5,7 @@
<columns>
<column name="autologin_key" var="autologin_key" notnull="notnull" minlength="1" maxlength="80" />
<column name="security_key" var="security_key" notnull="notnull" minlength="1" maxlength="80" />
<column name="previous_key" var="previous_key" />
<column name="member_srl" var="member_srl" notnull="notnull" filter="number" />
<column name="regdate" var="regdate" default="curdate()" />
<column name="ipaddress" var="ipaddress" default="ipaddress()" />

View file

@ -4,6 +4,7 @@
</tables>
<columns>
<column name="security_key" var="security_key" />
<column name="previous_key" var="previous_key" />
<column name="last_visit" var="last_visit" default="curdate()" />
<column name="last_ipaddress" var="last_ipaddress" default="ipaddress()" />
<column name="user_agent" var="user_agent" />

View file

@ -2,6 +2,7 @@
<column name="id" type="number" primary_key="primary_key" auto_increment="auto_increment" />
<column name="autologin_key" type="varchar" size="80" notnull="notnull" unique="unique_autologin_key" />
<column name="security_key" type="varchar" size="80" notnull="notnull" />
<column name="previous_key" type="varchar" size="80" />
<column name="member_srl" type="number" notnull="notnull" index="idx_member_srl" />
<column name="regdate" type="date" index="idx_regdate" />
<column name="ipaddress" type="varchar" size="60" />