PHP、nodeJS 和 session

标签 php node.js sockets session keep-alive

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

最佳答案

您可以使用 memcached as your session storage handler in PHP . Memcached 是一个简单的键值存储,可以通过 TCP 访问;有一个memcached module available for Node.js .

PHP 将session 以session id 为key 存储在memcached 中。存储在 memcached 中的 session 数据(值)是一个序列化的 PHP 对象,稍作改动。您可以在 the SO question "Parse PHP Session in Javascript" 阅读更多关于这种不寻常的序列化的信息。 .幸运的是,那里已经有一个 NPM 模块: php-unserialize .


现在介绍操作方法。

假设

  • 可在 127.0.0.1:11211 访问 memcached
  • 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);

php s.php 执行它,它应该把东西放在标准输出中:

74ibpvem1no6ssros60om3mlo5
Array
(
    [some] => thing
)

好的,现在我们知道 session ID ( 74ibpvem1no6ssros60om3mlo5 ),并确认 session 数据已设置。要确认它在 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";

到目前为止,我们已经 1) 在 php 中创建了一个 session ID,2) 在 memcached 中存储了来自 php 的 session 数据,以及 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
});

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

fetching data with key: 74ibpvem1no6ssros60om3mlo5
raw data: some|s:5:"thing";
parsed obj: { some: 'thing' }

警告/陷阱

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

关于PHP、nodeJS 和 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24296212/

相关文章:

php - cloudflare api 将 curl 转换为 php curl 并发送 CNAME 更新

php - Laravel - 首先从数据库中获取特定行

javascript - 提取表单数据并使用 node.js 发送到我的数据库

node.js - 图像水印,nodejs显示错误

python - socket.gethostname() 返回错误的主机名

javascript - Socket.io 和 Node.Js 多服务器

php - 将 CSS 应用于 Iframe 内容

php - 如何在 laravel 的 Controller 中获取 url 参数?

node.js - Socket.io 'on' 返回未定义

c# - C#SocketAsyncEventArgs停止触发完成的事件