Добрый день. Увидев статейку на тему «умных сессий», я решил поделиться действительно умной схемой, которая по всем параметрам превосходит предложенную.
Задача
Реализовать оптимальную систему пользовательских сессий и авторизации, с возможностью «Выйти на всех компьютерах». Защитить систему от сбоев (перезагрузки memcached), обеспечить эффективное использование памяти.
Реализация
1. Нужно сделать обертку для хранения (см. код №1). Код безусловно необходимо адаптировать под вашу систему (например, указать путь до memcache-объекта).
2. Использовать $session->start(); только в тех случаях когда действительно нужно получить доступ к сессии (например, в контроллере авторизации). Для получения ID сессии — использовать $session->getId().
3. Для авторизации завести таблицу в СУБД (см. код №2). В ней хранятся идентификаторы сессий и соответствующие им ID пользователей. При успешном вводе аутентификационных данных, необходимо вставить в таблицу соответствующий ряд, а также внести в memcached ключ «al.» => .
При обращении некоего пользователя на страницу, необходимо запросить $session->getId(), и в случае если возращена строка — проверить сначала соответствующий в memcached, если он не обнаружен, запросить таблицу authsessions (и вставить в memcached), и использовать полученный UID как таковой.
При нажатии на кнопку «Выйти на всех компьютерах», необходимо запросить из таблицы authsessions все сессии с таким UID и удалить сначала из СУБД, затем из memcached.
Код №1:
Код №2:
Задача
Реализовать оптимальную систему пользовательских сессий и авторизации, с возможностью «Выйти на всех компьютерах». Защитить систему от сбоев (перезагрузки memcached), обеспечить эффективное использование памяти.
Реализация
1. Нужно сделать обертку для хранения (см. код №1). Код безусловно необходимо адаптировать под вашу систему (например, указать путь до memcache-объекта).
2. Использовать $session->start(); только в тех случаях когда действительно нужно получить доступ к сессии (например, в контроллере авторизации). Для получения ID сессии — использовать $session->getId().
3. Для авторизации завести таблицу в СУБД (см. код №2). В ней хранятся идентификаторы сессий и соответствующие им ID пользователей. При успешном вводе аутентификационных данных, необходимо вставить в таблицу соответствующий ряд, а также внести в memcached ключ «al.» => .
При обращении некоего пользователя на страницу, необходимо запросить $session->getId(), и в случае если возращена строка — проверить сначала соответствующий в memcached, если он не обнаружен, запросить таблицу authsessions (и вставить в memcached), и использовать полученный UID как таковой.
При нажатии на кнопку «Выйти на всех компьютерах», необходимо запросить из таблицы authsessions все сессии с таким UID и удалить сначала из СУБД, затем из memcached.
Код №1:
<?php
$session = new session;
class session
{
public $lifeTime = 86400;
public $started = FALSE;
public function __construct ()
{
ini_set('session.cookie_lifetime',157680000);
ini_set('session.cookie_domain',COOKDOMAIN);
ini_set('session.name',COOKPREFIX.'sid');
ini_set('session.use_trans_sid',0);
ini_set('session.use_cookies',1);
}
public function getId()
{
$sn = ini_get('session.name');
if (isset($_REQUEST[$sn])) {return gpcvar_str($_REQUEST[$sn]);}
if (isset($_COOKIE[$sn])) {return gpcvar_str($_COOKIE[$sn]);}
$this->start();
return session_id();
}
public function start()
{
if ($this->started) {return;}
$this->started = TRUE;
$sn = ini_get('session.name');
session_set_save_handler(array($this,'open'),array($this,'close'),array($this,'read'),array($this,'write'),array($this,'destroy'),array($this,'gc'));
if (isset($_REQUEST[$sn])) {$_COOKIE[$sn] = gpcvar_str($_REQUEST[$sn]);}
session_start();
}
public function session_write_close() {return TRUE;}
public function open($savePath,$sessName) {return TRUE;}
public function close() {return TRUE;}
public function read($sessID) {return xE::$memcache->get('sess.'.$sessID);}
public function write($sessID,$sessData) {return xE::$memcache->set('sess.'.$sessID,$sessData,$this->lifeTime);}
public function destroy($sessID) {return xE::$memcache->delete('sess.'.$sessID);}
public function gc($lt) {return TRUE;}
}
function gpcvar_str(&$var) {if (is_array($var)) {return '';} return strval($var);}
* This source code was highlighted with Source Code Highlighter.
Код №2:
CREATE TABLE `xE_authsessions` (
`session_id` char(32) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`uid` int(11) NOT NULL,
`ip` int(10) unsigned NOT NULL,
`ctime` int(11) NOT NULL,
PRIMARY KEY (`session_id`),
KEY `uid` (`uid`)
) ENGINE=InnoDB;
* This source code was highlighted with Source Code Highlighter.