PHP,nodeJS和会话

Mag*_*gix 8 php sockets session keep-alive node.js

我有一个传统的apache服务器提供php文件,以及一个nodeJS服务器(带有socket.io,但没有表达/连接)用于PHP网站上的实时事件管理.我有时需要对连接到nodeJS服务器的客户端进行身份验证,但是当用户重新加载页面时,此身份验证会丢失,因为它还会重新加载socket.io客户端(我将套接字ID存储在服务器上,每次刷新时都会丢失)
问题是:有没有办法在socket.io中保持连接活动,或者是一种链接apache PHP会话和nodeJS服务器的方法?或者也许是一种使用cookie保持此身份验证的方法(知道我必须存储敏感数据,如用户密码和密钥)?

zam*_*uts 10

您可以memcached在PHP中用作会话存储处理程序.Memcached是一个简单的键值存储,可以通过TCP访问; 有一个可用于Node.jsmemcached模块.

PHP使用会话ID作为密钥将会话存储在memcached中.存储在memcached中的会话数据(值)是一个序列化的PHP对象,略有不同.您可以在SO问题"在Javascript中解析PHP会话"中阅读有关此异常序列化的更多信息.幸运的是,那里已经有了一个NPM模块:php-unserialize.


现在为How-To.

假设

  • memcached可在127.0.0.1:111211访问
  • php.ini(或php.d/memcache.ini)配置为:session.save_handler='memcached'session.save_path='tcp://127.0.0.1:11211'
  • 您已安装所需的NPM模块(2): npm install memcached php-unserialize
  • 你对CLI没问题

准备

首先,只是为了获得一些测试数据,保存以下php脚本(s.php):

<?php
session_start();
$_SESSION['some'] = 'thing';
echo session_id()."\n";
print_r($_SESSION);
Run Code Online (Sandbox Code Playgroud)

执行它php s.php,它应该把东西放在stdout中:

74ibpvem1no6ssros60om3mlo5
Array
(
    [some] => thing
)
Run Code Online (Sandbox Code Playgroud)

好的,现在我们知道会话id(74ibpvem1no6ssros60om3mlo5),并确认已设置会话数据.要确认它是在memcached中,你可以运行memcached-tool 127.0.0.1:11211 dump它提供已知键:值对的转储,例如我在我的测试床上有两个:

Dumping memcache contents
  Number of buckets: 1
  Number of items  : 3
Dumping bucket 2 - 3 total items
add 74ibpvem1no6ssros60om3mlo5 0 1403169638 17
some|s:5:"thing";
add 01kims55ut0ukcko87ufh9dpv5 0 1403168854 17
some|s:5:"thing";
Run Code Online (Sandbox Code Playgroud)

到目前为止,我们已经1)在php中创建了一个会话ID,2)在memcached中存储了来自php的会话数据,并且3)通过CLI确认了数据存在.

使用Node.js进行检索

这部分实际上非常简单.NPM模块已经完成了大部分繁重的工作.我编写了一个通过CLI运行的小Node.js脚本,但是你得到了图片:

var Memcached = require('memcached');
var PHPUnserialize = require('php-unserialize');

var mem = new Memcached('127.0.0.1:11211'); // connect to local memcached
var key = process.argv[2]; // get from CLI arg

console.log('fetching data with key:',key);
mem.get(key,function(err,data) { // fetch by key
        if ( err ) return console.error(err); // if there was an error
        if ( data === false ) return console.error('could not retrieve data'); // data is boolean false when the key does not exist
        console.log('raw data:',data); // show raw data
        var o = PHPUnserialize.unserializeSession(data); // decode session data
        console.log('parsed obj:',o); // show unserialized object
});
Run Code Online (Sandbox Code Playgroud)

假设上面的内容保存为m.js,可以运行,node m.js 74ibpvem1no6ssros60om3mlo5输出如下:

fetching data with key: 74ibpvem1no6ssros60om3mlo5
raw data: some|s:5:"thing";
parsed obj: { some: 'thing' }
Run Code Online (Sandbox Code Playgroud)

警告/陷阱

我的一个PHP应用程序将一些二进制数据存储在会话值中(即加密),但是密钥和普通会话对象保持不变(如上例所示).在这种情况下,memcached-tool <host:port> dump将格式错误的序列化会话字符串打印到stdout; 我认为这可能与stdout隔离,但我错了.使用时PHPUnserialize.unserializeSession,它也无法解析数据(由分隔|).我在网上尝试了一些其他会话反序列化方法,但没有任何成功.我假设memcached在内部维护正确的数据,因为它与本机PHP会话保存处理程序一起使用,因此,在撰写本文时,我不太确定它是否是反序列化方法或者memcached NPM模块是否仅仅是正确检索/解释数据.当坚持使用ascii或utf-8等非二进制数据时,它应该按预期工作.