mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-05-20 17:58:24 +03:00
Поддержка нескольких авторизаций для одного пользователя
This commit is contained in:
parent
1fdc7d2398
commit
e4bcd5391b
|
@ -79,12 +79,34 @@ class ModuleUser extends Module
|
|||
* Проверяем есть ли у юзера сессия, т.е. залогинен или нет
|
||||
*/
|
||||
$sUserId = $this->Session_Get('user_id');
|
||||
$sSessionKey = $this->Session_Get('session_key');
|
||||
if ($sUserId and $oUser = $this->GetUserById($sUserId) and $oUser->getActivate()) {
|
||||
if ($this->oSession = $oUser->getSession()) {
|
||||
/**
|
||||
* Проверяем сессию
|
||||
*/
|
||||
if ($oSession = $oUser->getSession()) {
|
||||
$bSessionValid = false;
|
||||
/**
|
||||
* Сюда можно вставить условие на проверку айпишника сессии
|
||||
* Т.к. у пользователя может быть несколько сессий (разные браузеры), то нужно дополнительно сверить
|
||||
*/
|
||||
$this->oUserCurrent = $oUser;
|
||||
if ($oSession->getKey() == $sSessionKey and $oSession->isActive()) {
|
||||
$bSessionValid = true;
|
||||
} else {
|
||||
/**
|
||||
* Пробуем скорректировать сессию
|
||||
*/
|
||||
if ($oSession = $this->oMapper->GetSessionByKey($sSessionKey) and $oSession->getUserId() == $oUser->getId() and $oSession->isActive()) {
|
||||
$bSessionValid = true;
|
||||
$oUser->setSession($oSession);
|
||||
}
|
||||
}
|
||||
if ($bSessionValid) {
|
||||
/**
|
||||
* Сюда можно вставить условие на проверку айпишника сессии
|
||||
*/
|
||||
$this->oUserCurrent = $oUser;
|
||||
$this->oSession = $oSession;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
@ -548,7 +570,7 @@ class ModuleUser extends Module
|
|||
*
|
||||
* @param ModuleUser_EntityUser $oUser Объект пользователя
|
||||
* @param bool $bRemember Запоминать пользователя или нет
|
||||
* @param string $sKey Ключ авторизации для куков
|
||||
* @param string $sKey Уникальный ключ сессии
|
||||
* @return bool
|
||||
*/
|
||||
public function Authorization(ModuleUser_EntityUser $oUser, $bRemember = true, $sKey = null)
|
||||
|
@ -556,12 +578,6 @@ class ModuleUser extends Module
|
|||
if (!$oUser->getId() or !$oUser->getActivate()) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Генерим новый ключ авторизаии для куков
|
||||
*/
|
||||
if (is_null($sKey)) {
|
||||
$sKey = md5(func_generator() . time() . $oUser->getLogin());
|
||||
}
|
||||
/**
|
||||
* Создаём новую сессию
|
||||
*/
|
||||
|
@ -572,12 +588,14 @@ class ModuleUser extends Module
|
|||
* Запоминаем в сесси юзера
|
||||
*/
|
||||
$this->Session_Set('user_id', $oUser->getId());
|
||||
$this->Session_Set('session_key', $this->oSession->getKey());
|
||||
$this->oUserCurrent = $oUser;
|
||||
/**
|
||||
* Ставим куку
|
||||
*/
|
||||
if ($bRemember) {
|
||||
$this->Session_SetCookie('key', $sKey, time() + Config::Get('sys.cookie.time'), false, true);
|
||||
$this->Session_SetCookie('key', $this->oSession->getKey(), time() + Config::Get('module.user.time_login_remember'), false,
|
||||
true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -592,8 +610,8 @@ class ModuleUser extends Module
|
|||
return;
|
||||
}
|
||||
if (isset($_COOKIE['key']) and is_string($_COOKIE['key']) and $sKey = $_COOKIE['key']) {
|
||||
if ($oUser = $this->GetUserBySessionKey($sKey)) {
|
||||
$this->Authorization($oUser);
|
||||
if ($oUser = $this->GetUserBySessionKey($sKey) and $oSession = $this->oMapper->GetSessionByKey($sKey) and $oSession->isActive()) {
|
||||
$this->Authorization($oUser, true, $oSession->getKey());
|
||||
} else {
|
||||
$this->Logout();
|
||||
}
|
||||
|
@ -645,12 +663,23 @@ class ModuleUser extends Module
|
|||
*/
|
||||
public function Logout()
|
||||
{
|
||||
/**
|
||||
* Закрываем текущую сессию
|
||||
*/
|
||||
if ($this->oSession) {
|
||||
$this->oSession->setDateLast(date("Y-m-d H:i:s"));
|
||||
$this->oSession->setIpLast(func_getIp());
|
||||
$this->oSession->setDateClose(date("Y-m-d H:i:s"));
|
||||
$this->oMapper->UpdateSession($this->oSession);
|
||||
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('user_session_update'));
|
||||
}
|
||||
$this->oUserCurrent = null;
|
||||
$this->oSession = null;
|
||||
/**
|
||||
* Дропаем из сессии
|
||||
*/
|
||||
$this->Session_Drop('user_id');
|
||||
$this->Session_Drop('session_key');
|
||||
/**
|
||||
* Дропаем куку
|
||||
*/
|
||||
|
@ -688,17 +717,65 @@ class ModuleUser extends Module
|
|||
* @param string $sKey Сессионный ключ
|
||||
* @return bool
|
||||
*/
|
||||
protected function CreateSession(ModuleUser_EntityUser $oUser, $sKey)
|
||||
protected function CreateSession(ModuleUser_EntityUser $oUser, $sKey = null)
|
||||
{
|
||||
/**
|
||||
* Генерим новый ключ
|
||||
*/
|
||||
if (is_null($sKey)) {
|
||||
$sKey = md5(func_generator() . time() . $oUser->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяем ключ сессии
|
||||
*/
|
||||
if ($oSession = $this->oMapper->GetSessionByKey($sKey)) {
|
||||
/**
|
||||
* Если сессия уже не активна, то удаляем её
|
||||
*/
|
||||
if (!$oSession->isActive()) {
|
||||
$this->oMapper->DeleteSession($oSession);
|
||||
unset($oSession);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($oSession)) {
|
||||
/**
|
||||
* Проверяем количество активных сессий у пользователя и завершаем сверх лимита
|
||||
*/
|
||||
$iCountMaxSessions = Config::Get('module.user.count_auth_session');
|
||||
$aSessions = $this->GetSessionsByUserId($oUser->getId());
|
||||
$aSessions = array_slice($aSessions, ($iCountMaxSessions - 1 < 0) ? 0 : $iCountMaxSessions - 1);
|
||||
foreach ($aSessions as $oSessionOld) {
|
||||
$oSessionOld->setDateClose(date("Y-m-d H:i:s"));
|
||||
$this->oMapper->UpdateSession($oSessionOld);
|
||||
}
|
||||
/**
|
||||
* Проверяем количество всех сессий у пользователя и удаляем сверх лимита
|
||||
*/
|
||||
$iCountMaxSessions = Config::Get('module.user.count_auth_session_history');
|
||||
$aSessions = $this->GetSessionsByUserId($oUser->getId(), false);
|
||||
$aSessions = array_slice($aSessions, ($iCountMaxSessions - 1 < 0) ? 0 : $iCountMaxSessions - 1);
|
||||
foreach ($aSessions as $oSessionOld) {
|
||||
$this->oMapper->DeleteSession($oSessionOld);
|
||||
}
|
||||
}
|
||||
|
||||
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('user_session_update'));
|
||||
$this->Cache_Delete("user_session_{$oUser->getId()}");
|
||||
$oSession = Engine::GetEntity('User_Session');
|
||||
/**
|
||||
* Создаем новую или обновляем данные у старой
|
||||
*/
|
||||
if (!isset($oSession)) {
|
||||
$oSession = Engine::GetEntity('User_Session');
|
||||
$oSession->setKey($sKey);
|
||||
$oSession->setIpCreate(func_getIp());
|
||||
$oSession->setDateCreate(date("Y-m-d H:i:s"));
|
||||
}
|
||||
$oSession->setUserId($oUser->getId());
|
||||
$oSession->setKey($sKey);
|
||||
$oSession->setIpLast(func_getIp());
|
||||
$oSession->setIpCreate(func_getIp());
|
||||
$oSession->setDateLast(date("Y-m-d H:i:s"));
|
||||
$oSession->setDateCreate(date("Y-m-d H:i:s"));
|
||||
|
||||
if ($this->oMapper->CreateSession($oSession)) {
|
||||
$this->oSession = $oSession;
|
||||
return true;
|
||||
|
@ -706,22 +783,9 @@ class ModuleUser extends Module
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список юзеров по дате последнего визита
|
||||
*
|
||||
* @param int $iLimit Количество
|
||||
* @return array
|
||||
*/
|
||||
public function GetUsersByDateLast($iLimit = 20)
|
||||
public function GetSessionsByUserId($iUserId, $bOnlyNotClose = true)
|
||||
{
|
||||
if ($this->IsAuthorization()) {
|
||||
$data = $this->oMapper->GetUsersByDateLast($iLimit);
|
||||
} elseif (false === ($data = $this->Cache_Get("user_date_last_{$iLimit}"))) {
|
||||
$data = $this->oMapper->GetUsersByDateLast($iLimit);
|
||||
$this->Cache_Set($data, "user_date_last_{$iLimit}", array("user_session_update"), 60 * 60 * 24 * 2);
|
||||
}
|
||||
$data = $this->GetUsersAdditionalData($data);
|
||||
return $data;
|
||||
return $this->oMapper->GetSessionsByUserId($iUserId, $bOnlyNotClose);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -87,6 +87,28 @@ class ModuleUser_EntitySession extends Entity
|
|||
return $this->_getDataOne('session_date_last');
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает дату закрытия сессии
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDateClose()
|
||||
{
|
||||
return $this->_getDataOne('session_date_close');
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет факт активности сессии
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isActive() {
|
||||
if ($this->getDateClose()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Устанавливает ключ сессии
|
||||
|
@ -147,4 +169,14 @@ class ModuleUser_EntitySession extends Entity
|
|||
{
|
||||
$this->_aData['session_date_last'] = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает дату закрытия сессии
|
||||
*
|
||||
* @param string $data
|
||||
*/
|
||||
public function setDateClose($data)
|
||||
{
|
||||
$this->_aData['session_date_close'] = $data;
|
||||
}
|
||||
}
|
|
@ -451,10 +451,11 @@ class ModuleUser_EntityUser extends Entity
|
|||
$iSize .= 'crop';
|
||||
}
|
||||
|
||||
if ( $this->getProfileAvatar() ) {
|
||||
if ($this->getProfileAvatar()) {
|
||||
return $this->Media_GetImageWebPath($this->getProfileAvatar(), $iSize);
|
||||
} else {
|
||||
return $this->Media_GetImagePathBySize(Config::Get('path.skin.assets.web') . '/images/avatars/avatar_' . ($this->getProfileSex() == 'woman' ? 'female' : 'male') . '.png', $iSize);
|
||||
return $this->Media_GetImagePathBySize(Config::Get('path.skin.assets.web') . '/images/avatars/avatar_' . ($this->getProfileSex() == 'woman' ? 'female' : 'male') . '.png',
|
||||
$iSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,7 +470,7 @@ class ModuleUser_EntityUser extends Entity
|
|||
$aAvatars = array();
|
||||
|
||||
foreach (Config::Get('module.user.avatar_size') as $sSize) {
|
||||
$aAvatars[ $sSize ] = $this->getProfileAvatarPath( $sSize );
|
||||
$aAvatars[$sSize] = $this->getProfileAvatarPath($sSize);
|
||||
}
|
||||
|
||||
return $aAvatars;
|
||||
|
|
|
@ -141,6 +141,41 @@ class ModuleUser_MapperUser extends Mapper
|
|||
return null;
|
||||
}
|
||||
|
||||
public function GetSessionByKey($sKey)
|
||||
{
|
||||
$sql = "SELECT
|
||||
s.*
|
||||
FROM
|
||||
" . Config::Get('db.table.session') . " as s
|
||||
WHERE
|
||||
s.session_key = ?
|
||||
";
|
||||
if ($aRow = $this->oDb->selectRow($sql, $sKey)) {
|
||||
return Engine::GetEntity('User_Session', $aRow);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetSessionsByUserId($iUserId, $bOnlyNotClose = true)
|
||||
{
|
||||
$sql = "SELECT
|
||||
s.*
|
||||
FROM
|
||||
" . Config::Get('db.table.session') . " as s
|
||||
WHERE
|
||||
s.user_id = ?d
|
||||
{ and 1=?d and s.session_date_close is null }
|
||||
ORDER BY session_date_last desc
|
||||
";
|
||||
$aRes = array();
|
||||
if ($aRows = $this->oDb->select($sql, $iUserId, $bOnlyNotClose ? 1 : DBSIMPLE_SKIP)) {
|
||||
foreach ($aRows as $aRow) {
|
||||
$aRes[] = Engine::GetEntity('User_Session', $aRow);
|
||||
}
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание пользовательской сессии
|
||||
*
|
||||
|
@ -173,10 +208,27 @@ class ModuleUser_MapperUser extends Mapper
|
|||
$sql = "UPDATE " . Config::Get('db.table.session') . "
|
||||
SET
|
||||
session_ip_last = ? ,
|
||||
session_date_last = ?
|
||||
WHERE user_id = ?
|
||||
session_date_last = ?,
|
||||
session_date_close = ?
|
||||
WHERE session_key = ?
|
||||
";
|
||||
$res = $this->oDb->query($sql, $oSession->getIpLast(), $oSession->getDateLast(), $oSession->getUserId());
|
||||
$res = $this->oDb->query($sql, $oSession->getIpLast(), $oSession->getDateLast(), $oSession->getDateClose(),
|
||||
$oSession->getKey());
|
||||
return $this->IsSuccessful($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление сессии
|
||||
*
|
||||
* @param ModuleUser_EntitySession $oSession
|
||||
* @return int|bool
|
||||
*/
|
||||
public function DeleteSession(ModuleUser_EntitySession $oSession)
|
||||
{
|
||||
$sql = "DELETE FROM " . Config::Get('db.table.session') . "
|
||||
WHERE session_key = ?
|
||||
";
|
||||
$res = $this->oDb->query($sql, $oSession->getKey());
|
||||
return $this->IsSuccessful($res);
|
||||
}
|
||||
|
||||
|
@ -195,9 +247,20 @@ class ModuleUser_MapperUser extends Mapper
|
|||
$sql = "SELECT
|
||||
s.*
|
||||
FROM
|
||||
" . Config::Get('db.table.session') . " as s
|
||||
WHERE
|
||||
s.user_id IN(?a) ";
|
||||
(
|
||||
SELECT
|
||||
user_id, max(session_date_last) as max_date_last
|
||||
FROM
|
||||
" . Config::Get('db.table.session') . "
|
||||
WHERE
|
||||
user_id IN (?a)
|
||||
GROUP BY user_id
|
||||
) as s2,
|
||||
" . Config::Get('db.table.session') . " as s
|
||||
WHERE
|
||||
s2.user_id = s.user_id and s2.max_date_last = s.session_date_last
|
||||
";
|
||||
|
||||
$aRes = array();
|
||||
if ($aRows = $this->oDb->select($sql, $aArrayId)) {
|
||||
foreach ($aRows as $aRow) {
|
||||
|
@ -293,31 +356,6 @@ class ModuleUser_MapperUser extends Mapper
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список юзеров по дате последнего визита
|
||||
*
|
||||
* @param int $iLimit Количество
|
||||
* @return array
|
||||
*/
|
||||
public function GetUsersByDateLast($iLimit)
|
||||
{
|
||||
$sql = "SELECT
|
||||
user_id
|
||||
FROM
|
||||
" . Config::Get('db.table.session') . "
|
||||
ORDER BY
|
||||
session_date_last DESC
|
||||
LIMIT 0, ?d
|
||||
";
|
||||
$aReturn = array();
|
||||
if ($aRows = $this->oDb->select($sql, $iLimit)) {
|
||||
foreach ($aRows as $aRow) {
|
||||
$aReturn[] = $aRow['user_id'];
|
||||
}
|
||||
}
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список юзеров по дате регистрации
|
||||
*
|
||||
|
@ -365,9 +403,9 @@ class ModuleUser_MapperUser extends Mapper
|
|||
*/
|
||||
public function GetCountUsersActive($sDateActive)
|
||||
{
|
||||
$sql = "SELECT count(*) as count FROM " . Config::Get('db.table.session') . " WHERE session_date_last >= ? ";
|
||||
$result = $this->oDb->selectRow($sql, $sDateActive);
|
||||
return $result['count'];
|
||||
$sql = "SELECT DISTINCT user_id FROM " . Config::Get('db.table.session') . " WHERE session_date_last >= ? ";
|
||||
$result = $this->oDb->select($sql, $sDateActive);
|
||||
return $result ? count($result) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1356,7 +1394,7 @@ class ModuleUser_MapperUser extends Mapper
|
|||
}
|
||||
|
||||
$sql = "SELECT
|
||||
u.user_id
|
||||
DISTINCT u.user_id
|
||||
FROM
|
||||
" . Config::Get('db.table.user') . " as u
|
||||
{ JOIN " . Config::Get('db.table.geo_target') . " as g ON ( u.user_id=g.target_id and g.country_id = ? ) }
|
||||
|
|
|
@ -157,6 +157,7 @@ $config['module']['user']['login']['max_size'] = 30; // Максимальное
|
|||
$config['module']['user']['login']['charset'] = '0-9a-z_\-'; // Допустимые в имени пользователя символы
|
||||
$config['module']['user']['time_active'] = 60 * 60 * 24 * 7; // Число секунд с момента последнего посещения пользователем сайта, в течение которых он считается активным
|
||||
$config['module']['user']['time_onlive'] = 60 * 10; // Число секунд с момента последнего посещения пользователем сайта, в течение которых он считается "онлайн"
|
||||
$config['module']['user']['time_login_remember'] = 60 * 60 * 24 * 7; // время жизни куки когда пользователь остается залогиненым на сайте, 7 дней
|
||||
$config['module']['user']['usernote_text_max'] = 250; // Максимальный размер заметки о пользователе
|
||||
$config['module']['user']['usernote_per_page'] = 20; // Число заметок на одну страницу
|
||||
$config['module']['user']['userfield_max_identical'] = 2; // Максимальное число контактов одного типа
|
||||
|
@ -173,6 +174,8 @@ $config['module']['user']['complaint_type'] = array( // Список типо
|
|||
'other'
|
||||
);
|
||||
$config['module']['user']['rbac_role_default'] = 'user'; // Роль, которая автоматически назначается пользователю при регистрации
|
||||
$config['module']['user']['count_auth_session'] = 4; // Количество разрешенных сессий пользователя (авторизаций в разных браузерах)
|
||||
$config['module']['user']['count_auth_session_history'] = 10; // Общее количество сессий для хранения (значение должно быть больше чем count_auth_session)
|
||||
|
||||
// Модуль Comment
|
||||
$config['module']['comment']['per_page'] = 20; // Число комментариев на одну страницу(это касается только полного списка комментариев прямого эфира)
|
||||
|
|
|
@ -744,4 +744,11 @@ INSERT INTO `prefix_topic_type` (`id`, `name`, `name_many`, `code`, `allow_remov
|
|||
|
||||
-- 17.12.2014
|
||||
ALTER TABLE `prefix_user` CHANGE `user_settings_timezone` `user_settings_timezone` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;
|
||||
ALTER TABLE `prefix_user` ADD `user_admin` TINYINT(1) NOT NULL DEFAULT '0' AFTER `user_mail`, ADD INDEX (`user_admin`) ;
|
||||
ALTER TABLE `prefix_user` ADD `user_admin` TINYINT(1) NOT NULL DEFAULT '0' AFTER `user_mail`, ADD INDEX (`user_admin`) ;
|
||||
|
||||
|
||||
-- 27.12.2014
|
||||
ALTER TABLE `prefix_session` DROP FOREIGN KEY `prefix_session_fk`;
|
||||
ALTER TABLE `prefix_session` DROP INDEX user_id;
|
||||
ALTER TABLE `prefix_session` ADD INDEX(`user_id`);
|
||||
ALTER TABLE `prefix_session` ADD `session_date_close` DATETIME NULL DEFAULT NULL , ADD INDEX (`session_date_close`) ;
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
set_time_limit(0);
|
||||
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
|
|
Loading…
Reference in a new issue