Как показать все пользовательские сессии в symfony2? И как убить некоторых из них?

1

Мне нужно управлять сеансами пользователя в Symfony2.

У меня есть проект с длительным периодом сеанса.

  1. Показать список всех активных сеансов пользователя. Например: когда кто-то использует мой логин/пароль, я хочу его увидеть.

  2. Удалите некоторую сессию. Например: если я понимаю, что какая-то сессия является злоумышленником, я могу ее удалить.

Я нашел в официальной документации Symfony, как установить пользовательский обработчик сеанса, но я не могу понять, как установить user_id там для поиска сеансов по этому параметру.

По умолчанию структура таблицы для обработчика сеанса Db:

CREATE TABLE 'sessions' (
    'sess_id' VARBINARY(128) NOT NULL PRIMARY KEY,
    'sess_data' BLOB NOT NULL,
    'sess_time' INTEGER UNSIGNED NOT NULL,
    'sess_lifetime' MEDIUMINT NOT NULL
) COLLATE utf8_bin, ENGINE = InnoDB;
  • 0
    Вы должны реализовать свой собственный обработчик сеанса или найти третий пакет. Symfony не может сделать это для вас с установкой по умолчанию. Информация о пользователях находится в столбце sess_data в сериализованной форме.
Теги:
session

1 ответ

1
Лучший ответ

ОК. Я нашел решение!) Я беру обработчик pdo, а затем добавляю два поля (user_id и agent), чтобы найти сеанс текущего пользователя и показать информацию о нем.

  1. Создать пользовательский обработчик

config.yml

framework:
       handler_id: session.handler.pdo.custom

services.yml

services:
    session.handler.pdo.custom:
        class: YourBundle\HttpFoundation\Session\Storage\Handler\UserIdPdoSessionHandler
        public:    true
        arguments:
            - "pgsql:host=%database_host%;dbname=%database_name%"
            - { db_username: %database_user%, db_password: %database_password% }
            - @security.token_storage

SQL для таблицы

CREATE TABLE sessions (sess_id VARCHAR(128) NOT NULL, sess_data BYTEA NOT NULL, sess_time INT NOT NULL, sess_lifetime INT NOT NULL, user_id INT DEFAULT NULL, server_addr VARCHAR(255) DEFAULT NULL, agent TEXT DEFAULT NULL, PRIMARY KEY(sess_id)) 

Создайте действие контроллера для показа сеансов:

/**
 * @Route(name="user_profile_sessions_list", path="/sessions")
 *
 * @param Request $request
 *
 * @return Response
 */
public function sessionsListAction(Request $request)
{
    $user = $this->getUser();
    $sessions = $this->get('session.handler.pdo.custom')->getSessionsByUserId($user->getId());
    return $this->render('YourBundle:Profile:sessions.html.twig', array(
        'sessions' => $sessions,
    ));
}

Создайте действие контроллера для удаления сеансов:

/**
 * @Route(name="user_profile_sessions_delete", path="/sessions/delete/{sessionId}")
 *
 * @param Request $request
 *
 * @return Response
 */
public function sessionDeleteAction(Request $request, $sessionId)
{
    $em = $this->getDoctrine()->getManager();

    //Удалим сессию из БД (если это текущая сессия, то сделаем logout)
    if ($sessionId == $this->get('session')->getId()) {
        $redirect = $this->redirect($this->generateUrl('fos_user_security_logout'));
    } else {
        $this->get('session.handler.pdo.custom')->destroy($sessionId, $this->getUser()->getId());
        $redirect = $this->redirect($this->generateUrl('user_profile_sessions_list'));
    }

    return $redirect;
}

Если вы хотите, вы могли бы создать Entity:

<?php

namespace Uip\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Sessions
 *
 * @ORM\Table(name="sessions")
 * @ORM\Entity
 */
class Sessions
{
    /**
     * @var string
     * @ORM\Id
     * @ORM\Column(name="sess_id", type="string", length=128, nullable=false)
     */
    private $sessId;

    /**
     * @var string
     * @ORM\Column(name="sess_data", type="blob", nullable=false)
     */
    private $sessData;

    /**
     * @var integer
     * @ORM\Column(name="sess_time", type="integer", nullable=false)
     */
    private $sessTime;

    /**
     * @var integer
     * @ORM\Column(name="sess_lifetime", type="integer", nullable=false)
     */
    private $sessLifetime;

    /**
     * @var integer
     * @ORM\Column(name="user_id", type="integer", nullable=true)
     */
    private $userId;

    /**
     * @var string
     * @ORM\Column(name="server_addr", type="string", nullable=true)
     */
    private $serverAddr;

    /**
     * @var string
     * @ORM\Column(name="agent", type="text", nullable=true)
     */
    private $agent;


    /**
     * Get sessId
     *
     * @return string
     */
    public function getSessId()
    {
        return $this->sessId;
    }

    /**
     * Get sessData
     *
     * @return string
     */
    public function getSessData()
    {
        return $this->sessData;
    }

    /**
     * Set sessData
     *
     * @param string $sessData
     * @return Sessions
     */
    public function setSessData($sessData)
    {
        $this->sessData = $sessData;

        return $this;
    }

    /**
     * Get sessTime
     *
     * @return integer
     */
    public function getSessTime()
    {
        return $this->sessTime;
    }

    /**
     * Set sessTime
     *
     * @param integer $sessTime
     * @return Sessions
     */
    public function setSessTime($sessTime)
    {
        $this->sessTime = $sessTime;

        return $this;
    }

    /**
     * Get sessLifetime
     *
     * @return integer
     */
    public function getSessLifetime()
    {
        return $this->sessLifetime;
    }

    /**
     * Set sessLifetime
     *
     * @param integer $sessLifetime
     * @return Sessions
     */
    public function setSessLifetime($sessLifetime)
    {
        $this->sessLifetime = $sessLifetime;

        return $this;
    }

    /**
     * Get userId
     *
     * @return integer
     */
    public function getUserId()
    {
        return $this->userId;
    }

    /**
     * Set userId
     *
     * @param integer $userId
     * @return Sessions
     */
    public function setUserId($userId)
    {
        $this->userId = $userId;

        return $this;
    }

    /**
     * Get serverAddr
     *
     * @return string
     */
    public function getServerAddr()
    {
        return $this->serverAddr;
    }

    /**
     * Set serverAddr
     *
     * @param string $serverAddr
     * @return Sessions
     */
    public function setServerAddr($serverAddr)
    {
        $this->serverAddr = $serverAddr;

        return $this;
    }

    /**
     * Get agent
     *
     * @return string
     */
    public function getAgent()
    {
        return $this->agent;
    }

    /**
     * Set agent
     *
     * @param string $agent
     * @return Sessions
     */
    public function setAgent($agent)
    {
        $this->agent = $agent;

        return $this;
    }
}

И ведро файла:

{% extends '@Your/layout.html.twig' %}
{% block content %}
    <h3>{{ 'user.sessions.list' | trans }}</h3>

    <div class="panel panel-default">
        <div class="panel-body">
            <table class="table table-striped">
                {% for session in sessions %}
                    <tr>
                        <td>{{ session.sess_time|date('d.m.Y H:i:s') }}</td>
                        <td>{{ (session.sess_time + session.sess_lifetime)|date('d.m.Y H:i:s') }}</td>
                        <td>{{ session.server_addr }}</td>
                        <td>{{ session.agent }}</td>
                        {% if session.sess_id == app.session.id %}
                            <td><a href="{{ path('fos_user_security_logout') }}" type="button" class="btn btn-danger">Удалить</a>
                                Текущая
                            </td>
                        {% else %}
                            <td><a href="{{ path('user_profile_sessions_delete', {'sessionId' : session.sess_id}) }}"
                                   type="button" class="btn btn-danger">Delete</a></td>
                        {% endif %}
                    </tr>
                {% endfor %}
            </table>

        </div>
    </div>
{% endblock %}
  • 0
    куда вы передаете имя пользователя и агента в сеанс при его создании?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню