I need you help with my php session class. I can not understand, the class implements adequate work with sessions. By adequate work, I understand the security and correctness of the methods.
<?php
namespace Core;
class Session
{
/**
* @var string Название сесии
*/
private $name;
/**
* @var array Cookie сессии
*/
private $cookie;
/**
* @var int Время жизни сессии
*/
private $timeToLive;
/**
* Session constructor
* @see http://php.net/manual/ru/session.configuration.php Настройка во время выполнения
* @see http://php.net/manual/ru/function.session-set-cookie-params.php PHP session_set_cookie_params
* @param int $time_to_live Время жизни сессии (в минутах)
* @param string $name
* @param array $cookie
*/
public function __construct($time_to_live = 30, $name = "application.session", $cookie = [])
{
$this->timeToLive = $time_to_live;
// Изменяется имя сеанса (по умолчанию) на указанное (если есть) имя для конкретного приложения
$this->name = $name;
$this->cookie = $cookie;
// session.cookie_path определяет устанавливаемый путь в сессионной cookie
// session.cookie_domain определяет устанавливаемый домен в сессионной cookie
$this->cookie += [
'lifetime' => 0,
'path' => ini_get('session.cookie_path'),
'domain' => ini_get('session.cookie_domain'),
'secure' => isset($_SERVER['HTTPS']),
'httponly' => true
];
/*
* Указывается, что сеансы должны передаваться только с помощью файлов cookie,
* исключая возможность отправки идентификатора сеанса в качестве параметра «GET».
* Установка параметров cookie идентификатора сеанса. Эти параметры могут быть переопределены при инициализации
* обработчика сеанса, однако рекомендуется использовать значения по умолчанию, разрешающие отправку
* только по HTTPS (если имеется) и ограниченный доступ HTTP (без доступа к сценарию на стороне клиента).
*/
// Определяет, будет ли модуль использовать cookies для хранения идентификатора сессии на стороне клиента
ini_set('session.use_cookies', 1);
// Определяет, будет ли модуль использовать только cookies для хранения идентификатора сессии на стороне клиента
ini_set('session.use_only_cookies', 1);
session_set_cookie_params(
$this->cookie['lifetime'],
$this->cookie['path'],
$this->cookie['domain'],
$this->cookie['secure'],
$this->cookie['httponly']
);
}
public function __get($name)
{
switch ($name) {
case 'isActive':
return $this->getActive();
case 'id':
return $this->getId();
case 'name':
return isset($this->name) ? $this->name : $this->getName();
case 'isValid':
return $this->isValid();
}
}
public function __set($name, $value)
{
switch ($name) {
case 'id':
$this->setId($value);
break;
case 'name':
$this->setName($value);
break;
case 'timeToLive':
$this->timeToLive = $value * 60;
break;
}
}
/**
* Получение статуса активности сессии
* @see https://secure.php.net/manual/en/function.session-status.php PHP session_status
* @return bool Статус активности сессии
*/
private function getActive()
{
return session_status() === PHP_SESSION_ACTIVE;
}
/**
* Получение идентификатора текущей сессии.
* Метод является оберткой для реализации стандартного метода.
* @see https://secure.php.net/manual/ru/function.session-id.php PHP session_id
* @return string
*/
private function getId()
{
return session_id();
}
/**
* Получение имени сессии
* Метод является оберткой для реализации стандартного метода
* @see http://php.net/manual/ru/function.session-name.php PHP session_name
* @return string|null
*/
private function getName()
{
return $this->isActive ? session_name() : null;
}
private function isValid()
{
return !$this->isExpired() && $this->isFingerprint();
}
/**
* Проверка срока действия сессии
* @return bool
*/
private function isExpired()
{
$activity = isset($_SESSION['_last_activity']) ? $_SESSION['_last_activity'] : false;
if ($activity && ((time() - $activity) > $this->timeToLive)) {
return true;
}
$_SESSION['_last_activity'] = time();
return false;
}
/**
* Проверка клиента
* @return bool
*/
private function isFingerprint()
{
$hash = sha1($_SERVER['HTTP_USER_AGENT'] .
(ip2long($_SERVER['REMOTE_ADDR']) & ip2long('255.255.0.0')));
if (isset($_SESSION['_fingerprint'])) {
return $_SESSION['_fingerprint'] === $hash;
}
$_SESSION['_fingerprint'] = $hash;
return true;
}
/**
* Назначение идентификатора текущей сессии.
* Метод является оберткой для реализации стандартного метода.
* @see https://secure.php.net/manual/ru/function.session-id.php PHP session_id
* @param string $id Идентификатор сессии для текущей сессии
*/
private function setId($id)
{
session_id($id);
}
/**
* Установка имени сессии
* Метод является оберткой для реализации стандартного метода
* @see http://php.net/manual/ru/function.session-name.php PHP session_name
* @param $name
*/
public function setName($name)
{
if ($this->isActive) {
session_name($name);
}
}
/**
* Инициализация сессии
*/
public function open()
{
// Бездействие, если сессия была инициализирована ранее
if ($this->isActive) {
return;
}
session_start();
// Проверка на корректность инициализированнйо сессии
if (!$this->isActive) {
// TODO: Вывод исключения
}
}
/**
* Уничтожение сессии, включая все атрибуты. Метод имеет эффект только при наличии активной сессии.
* @see http://php.net/manual/ru/function.setcookie.php PHP setcookie
*/
public function destroy()
{
if ($this->isActive) {
$this->deleteAll();
setcookie(
$this->name,
time() - 42000,
$this->cookie['path'],
$this->cookie['domain'],
$this->cookie['secure'],
$this->cookie['httponly']
);
session_destroy();
}
}
/**
* Удаление всех значений сессии
* Метод является оберткой для реализации стандартного метода
* @see http://php.net/manual/ru/function.session-unset.php PHP session_unset
*/
public function deleteAll()
{
if ($this->isActive) {
session_unset();
}
}
/**
* Обновление текущего ID на новый. Метод имеет эффект только при наличии активной сессии.
* @see https://secure.php.net/session_regenerate_id PHP session_regenerate_id
* @param bool $delete_old_session
*/
public function refresh($delete_old_session = true)
{
if ($this->isActive) {
session_regenerate_id($delete_old_session);
}
}
/**
* Получение значение сессии по ключу.
* @param string $key Ключ, по которому необходимо получить значения
* @return null|mixed Значение сессии по ключу
*/
public function get($key)
{
if ($this->isActive) {
return isset($_SESSION[$key]) ? $_SESSION[$key] : null;
}
return null;
}
/**
* Добавление или установка значений в сессию по ключу
* @param string $key Ключ, в который необходимо добавить значения
* @param string $value Значение добавления
*/
public function set($key, $value)
{
if ($this->isActive) {
$_SESSION[$key] = $value;
}
}
/**
* Удаление значения сессии по ключу
* @param string $key Ключ, по которому необходимо удалить значения
*/
public function delete($key)
{
if ($this->isActive && isset($_SESSION[$key])) {
unset($_SESSION[$key]);
}
}
/**
* Проверка наличия ключа у сессии
* @param string $key Ключ, в который необходимо найти
* @return bool
*/
public function hasKey($key)
{
return ($this->isActive && isset($_SESSION[$key]));
}
}
Usage
$session = new Session();
$session->open();
// If AFK more than access - logout
if (!$session->isValid) {
$session->destroy();
}
...
What are your thoughts and comments on this decision?