PHP会话:如何编辑其他用户的会话/编辑会话文件

时间:2019-03-28 22:39:32

标签: php session

编辑-2:针对此情况,请参阅Sam的解决方案。我将继续使用旧方法以及问题本身,但是基于Sam的解决方案构建了一个新的解决方案,该解决方案可在我保留的项目的github的存储库中找到

编辑-1:查看方法destroy(id)以找到解决方法

当前,在某些情况下,我的系统中需要使用其他值更新其他用户会话。现在,当执行某些操作时,当前案例需要在某些用户的会话文件中更改单个值。 在我的项目中,我创建了一个实现SessionHandlerInterface的SessionHandlerCustom类,并实现了一个逻辑,该逻辑为每个用户创建一个具有ID的自定义会话。我可以访问自定义目录中的文件,但奇怪的是,我无法对这些会话文件使用file_put_contents或file_get_contents。我尝试使用Session函数,并使用SessionHandlerCustom中提供的read()函数,使我能够使用SessionId从用户会话中获取所有内容。

工作方法 SessionFileGetValueByHashCode 是一种从Session获取内容的方法,并带有一些Key(通常是我想要的文件中的字段名称),它将获得确切的字符串。价值的关键。 第二种方法根本不起作用,它实际上是在Session中更改值的方法,但实际上没有。我尝试直接操作该文件没有成功,并且尝试使用SessionHandlerCustom-> write()方法,但没有效果。

任何人都可以帮助我,并解释一下如何更改/操纵其他用户的会话的正确方法吗?

系统示例:记录了一个普通用户,同时管理员使用Admin功能并为此用户更改一些值。如果该值不是每次都从数据库中获取的,则该当前登录用户的会话变量需要更改其值。

如果您感到好奇,那么系统是开源的,您可以在这里访问它: https://github.com/msiqueira-dev/InfraTools

\*
This should be in the class that implements SessionHandlerInterface. This will actually delete the users session and force it to reload the whole session when it makes another request. The $SavePath variable is variable create and stored with the directory folder of the Session.
*/
public function destroy($id)
    {
        $file = $this->SavePath . "/sess_" . $id;
        if (file_exists($file)) 
            unlink($file);
        return true;
    }

SessionFileGetValueByHashCode

//The &$Value will be filled with the whole $Key and its values presented in the Session File. For example: SomeValue|s:0:"";
public function SessionFileGetValueByHashCode(&$Value, $Application, $SessionId, $Key)
{
        $Value = NULL;
        if(isset($Application) && !empty($Application) && isset($SessionId) && !empty($SessionId) && isset($Key) && !empty($Key))
        {
            $file = SESSION_PATH . $Application . "/sess_" . $SessionId;
            if(file_exists(($file)))
            {
                $str = $this->InstanceSessionHandlerCustom->read($SessionId);
                $start = strpos($str, $Key);
                $end=$start;
                while($str[$end] != '"')
                {
                    $Value .= $str[$end];
                    $end++;
                }
                $Value .= '"';
                $end++;
                while($str[$end] != '"')
                {
                    $Value .= $str[$end];
                    $end++;
                }
                $Value .= '"';
                if($Value != NULL)
                    return Config::RET_OK;
            }
        }
        return Config::RET_ERROR;
    }

SessionFileUpdateValueByHashCode

public function SessionFileUpdateValueByHashCode($Application, $SessionId, $OldValue, $NewValue)
    {
        if(isset($Application) && !empty($Application) && isset($SessionId) && !empty($SessionId) 
                               && isset($OldValue) && !empty($OldValue) && isset($NewValue) && !empty($NewValue))
        {
            $file = SESSION_PATH . $Application . "/sess_" . $SessionId;
            if(file_exists(($file)))
            {
                $str = $this->InstanceSessionHandlerCustom->read($SessionId);
                $str = str_replace($OldValue, $NewValue, $str, $count);
                if($count > 0)
                {
                    echo $str . "<br>";
                    if($this->InstanceSessionHandlerCustom->write($SessionId, $str))
                        return Config::RET_OK;
                }
            }
        }
        return Config::RET_ERROR;
    }

2 个答案:

答案 0 :(得分:1)

  

谁能帮助我,并解释正确的方法是什么   更改/操纵其他用户的会话?

正确的方法是:您不

该会话旨在处理当前会话的数据,因此也称为名称。如果您干扰了其他人的会话,例如您的示例中的admin用户更改了该用户的数据,然后又要立即对其进行更新,那么您几乎肯定可以使用其他方法来获得更好的收益。

例如,您:

  1. 可以使用网络套接字将更改通知给用户客户端
  2. 可以使用令牌来验证用户会话中的数据是否仍然有效
  3. 可以使用一些持久性层(例如数据库)来传达更改

当然还有很多选择,我建议您重新考虑您的体系结构,并提出与更改其他用户会话不同的方法。

答案 1 :(得分:0)

可以 修改其他用户会话(请参见下文),尽管我个人建议这样做。正如我想象的那样,它可以打开会话劫持和其他漏洞的整个世界。

使用示例用例

  

将记录一个普通用户,而同时管理员使用Admin功能并为此用户更改一些值。如果该值不是每次都从数据库中获取的,则该当前登录用户的会话变量需要更改其值。

最好更新数据库中的值,然后在处理下一页之前先检查它是否已更改。 如果您不想在每个页面加载之前检查多个用户字段,则在管理面板中更新用户时,可以构建值的哈希并将其添加到名为session_hash的新列中。然后只需在页面加载时比较此字段即可

但是,如果您仍然想修改其他用户的会话,则可以将当前的session_id设置为目标。

// End my current session and save its id
session_start();
$my_session_id = session_id();
session_write_close();

// Modify our target session 
session_id($target_id);
session_start();
$_SESSION['is_logged_in'] = false;
session_write_close();

// Start our old session again
session_id($my_session_id);
session_start();

编辑

示例:https://www.samdjames.uk/session_example/index.php

示例Src:https://gist.github.com/SamJUK/c220e3742487567c6262238edf85695e