Как стать автором
Обновить

Действительно умные сессии и авторизация

Время на прочтение3 мин
Количество просмотров11K
Добрый день. Увидев статейку на тему «умных сессий», я решил поделиться действительно умной схемой, которая по всем параметрам превосходит предложенную.

Задача
Реализовать оптимальную систему пользовательских сессий и авторизации, с возможностью «Выйти на всех компьютерах». Защитить систему от сбоев (перезагрузки 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.
Теги:
Хабы:
Всего голосов 37: ↑23 и ↓14+9
Комментарии29

Публикации

Истории

Работа

PHP программист
99 вакансий

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань