【问题标题】:How to show all user sessions in symfony2? And how to kill some of them?如何在 symfony2 中显示所有用户会话?以及如何杀死其中一些?
【发布时间】:2016-01-29 19:20:49
【问题描述】:

我需要在 Symfony2 中管理用户会话。

我有一个会话周期长的项目。

  1. 显示所有活动用户会话的列表。 例如:当有人使用我的登录名/密码时,我想看到它。

  2. 删除一些会话。 例如:如果我知道某个会话是恶意的,我可以删除它。

我在 Symfony 官方文档中找到了如何安装 custom session handler ,但我不明白如何在此处设置 user_id 以通过此参数搜索会话。

默认情况下,Db session handler的表结构:

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;

【问题讨论】:

  • 您必须实现自己的自定义会话处理程序或找到第三个捆绑包。 Symfony 无法通过默认安装为您做到这一点。用户信息以序列化形式在sess_data列中。
  • 我创建了类似的问题,但与 Symfony5 相关:stackoverflow.com/questions/70035276/…

标签: php symfony session


【解决方案1】:

好的。我找到了解决方案!)我使用 pdo 处理程序,然后添加两个字段(user_id 和代理),以查找当前用户的会话并显示有关他的信息。

  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;
}

如果你愿意,你可以创建实体:

<?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 %}

【讨论】:

  • 在创建会话时将用户名和代理传递到哪里?
猜你喜欢
  • 1970-01-01
  • 2011-07-08
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
相关资源
最近更新 更多