Javascript 在PHP命令行中访问会话?

Javascript 在PHP命令行中访问会话?,javascript,php,session,websocket,Javascript,Php,Session,Websocket,我知道命令行不是web服务器,所以您无法访问$\u会话。但我不知道还能做什么 我一直遵循本教程使用WebSocket创建聊天: 我的问题是,我不知道如何安全地获取消息发送者的用户名。我可以将其包含在message send函数中,但因为它是Javascript,所以每个人都可以向其他人编辑自己的用户名 如何安全地获取用户的用户名,即$\u会话['username'] var Server; Server = new FancyWebSocket('ws://0.0.0.0:9000'); sen

我知道命令行不是web服务器,所以您无法访问
$\u会话
。但我不知道还能做什么

我一直遵循本教程使用WebSocket创建聊天:

我的问题是,我不知道如何安全地获取消息发送者的用户名。我可以将其包含在message send函数中,但因为它是Javascript,所以每个人都可以向其他人编辑自己的用户名

如何安全地获取用户的用户名,即
$\u会话['username']

var Server;
Server = new FancyWebSocket('ws://0.0.0.0:9000');
send( "test" );

我愿意接受各种建议,比如WebSocket的替代方案。我正在为我的网站创建实时聊天。当然,第一种选择是AJAX请求。AJAX不存在不能快速、轻松地访问WebSockets拥有的会话的问题。任何足够频繁的采样率都无法与实时进行区分

现在,我在WebSocket中实现了一个相当冗长的解决方案:

在握手期间,WebSocket服务器可以使用HTTP头,包括cookie。在您使用的服务器中,标头存储在
$headers
属性中

例如:

var_dump($user->headers);
array(14) {
  ["get"]=>
  string(8) "/echobot"
  ["host"]=>
  string(14) "127.0.0.1:9000"
  ...snip...
  ["cookie"]=>
   string(100) "PHPSESSID=jan9uknpc06mk4ddghph4870t1; MyCookie=My+Value%21%40%23%24%25; MyNonhttponlyCookie=My+Value"
}
这些cookie是从

session_start();
$_SESSION['Hi!'] = array('Hello!', 'where' => 'world!');
setcookie('MyCookie', 'My Value;!@#$%', 0, '/', '127.0.0.1', false, true);
setcookie('MyNonhttponlyCookie', 'My Value', 0, '/', '127.0.0.1', false, false);
因此,
$user->headers['cookie']
的值是一个分号和空格(
)分隔的键值对集合,其中的值是URL编码的,并用等号与其键分开。(如果在cookie名称中添加保留字符,PHP会发出投诉。因此cookie键不能包含任何url编码的值。)

提取这些信息的快速方法如下

$cookies = array();
$cookiesParts = explode('; ', $user->headers['cookie']);
foreach ($cookiesParts as $cookieParts) {
    $interimCookie = explode('=', $cookieParts);
    $cookies[$interimCookie[0]] = urldecode($interimCookie[1]);
}
var_dump($cookies);

array(3) {
  ["PHPSESSID"]=>
  string(26) "jan9uknpc06mk4ddghph4870t1"
  ["MyCookie"]=>
  string(14) "My Value;!@#$%"
  ["MyNonhttponlyCookie"]=>
  string(8) "My Value"
}
现在我们有了会话ID。使用
session\u name()
仔细检查,这将为您提供实际保存会话ID的cookie的密钥

我们可以序列化和取消序列化存储在服务器中的会话文件,它由
session\u save\u path()
指向。。。但是我想作弊

因为内置的会话系统会锁定会话文件,所以我们不能只打开会话文件并不断监视更改,也不能自己长时间锁定文件

如果我们可以使用
\uuu get()
\uu set()
魔术方法,就像我们使用
$\u SESSION
超全局(例如
$myUser->\u SESSION['key']='value';
)一样,这将是非常理想的,但是PHP不允许将这些方法视为数组。相反,我们必须设置一个更普通的命名方法

<?php
class MyUser extends WebSocketUser {
    public $session_id; // gets set somewhere. Good place is probably is your implementation of the `connected($user)` abstract method.

    public getSession($key) {
        session_id($this->session_id);
        session_start();
        $val = $_SESSION[$key];
        session_write_close(); // very important!
        return $val;
    }

    public setSession($key, $value) {
        session_id($this->session_id);
        session_start();
        $_SESSION[$key] = value;
        session_write_close(); // still very important!
    }
}

在握手期间,WS-server可以使用HTTP头(包括cookie)。在该特定服务器中,头在用户类中作为数组实现的属性
$headers
下可用。稍后我将添加一个完整的答案(并添加一个解析cookies的功能请求),但这将帮助您朝着正确的方向前进。您好,谢谢您的帮助!我真的不知道如何实现和使用MyUser类。您能帮我一下吗?在您的
FancyWebSocket
类中,您需要将受保护的属性
$userClass
指定为新用户类的名称。除此之外,这是基本的OOP。对不起,我没听清楚。我没有
FancyWebSocket
类,我有
PHPWebSocket
类。在我的任何文件中都没有名为
$userClass
的内容吗?@kopa抱歉,当时正在查看您在上面共享的JS片段,并假设您将PHP类命名为相同的,这就是
FancyWebSocket
的来源。当你说你正在跟随来自。。。你是说那一页上唯一的实际教程,它使用了?或者,您是指作为备选方案列出的其他几个方案中的一个吗?这看起来确实是一个有效的PHP会话ID。尝试一下,看看您得到了什么。