Примеры прокси сессии

Дата обновления перевода 2023-01-11

Примеры прокси сессии

Механизм прокси сессии имеет множество применений, и эта статья демонстрирует два наиболее распространённых. Вместо того, чтобы использовать обычный обработчик сессий, вы можете создаь пользовательский, просто определив класс, расширяющий класс SessionHandlerProxy.

После этого, определите класс, как сервис . Если вы используете конфигурацию services.yml по умолчанию , это случится автоматически.

Наконец, используйте опцию конфигурации framework.session.handler_id, чтобы сказать Symfony использовать ваш обработчик сессии, вместо установленного по умолчанию:

  • YAML
  • XML
  • PHP
1
2
3
4
5
# config/packages/framework.yaml
framework:
    session:
        # ...
        handler_id: App\Session\CustomSessionHandler

Продолжайте читать следующий раздел, чтобы узнать, как использовать обработчики сессиий на практике, чтобы решать два наиболее распространённых случая использования: шифрование информации о сессии и определение гостевых сессий только для чтения.

Шифрование данных сессии

Если вы хотите зашифровать данные сессии, вы можете использовать прокси для шифровки и расшифровки сессии. Следующий пример использует библиотеку php-encryption, но вы можете адаптировать его для любой другой используемой вами библиотеки:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// src/Session/EncryptedSessionProxy.php
namespace App\Session;

use Defuse\Crypto\Crypto;
use Defuse\Crypto\Key;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;

class EncryptedSessionProxy extends SessionHandlerProxy
{
    private $key;

    public function __construct(\SessionHandlerInterface $handler, Key $key)
    {
        $this->key = $key;

        parent::__construct($handler);
    }

    public function read($id)
    {
        $data = parent::read($id);

        return Crypto::decrypt($data, $this->key);
    }

    public function write($id, $data)
    {
        $data = Crypto::encrypt($data, $this->key);

        return parent::write($id, $data);
    }
}

Гостевые сессии только для чтения

Существуют приложения, где сессия требуется для гостевых пользователей, но где нет необходимости сохранять сессию. В этом случае, вы можете прервать сессию до того, как она будет записана:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// src/Session/ReadOnlySessionProxy.php
namespace App\Session;

use App\Entity\User;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;

class ReadOnlySessionProxy extends SessionHandlerProxy
{
    private $security;

    public function __construct(\SessionHandlerInterface $handler, Security $security)
    {
        $this->security = $security;

        parent::__construct($handler);
    }

    public function write($id, $data)
    {
        if ($this->getUser() && $this->getUser()->isGuest()) {
            return;
        }

        return parent::write($id, $data);
    }

    private function getUser()
    {
        $user = $this->security->getUser();
        if (is_object($user)) {
            return $user;
        }
    }
}