在 php 和 node 之间共享会话
Posted
技术标签:
【中文标题】在 php 和 node 之间共享会话【英文标题】:Share sessions between php and node 【发布时间】:2014-07-10 20:20:30 【问题描述】:最近有没有使用 node、express 和 redis/predis 共享 phpSESSID 的指南(或示例代码)?
我找到了几个 1-2 岁的教程,它们要么使用旧版本的 express,要么不使用 express。
Express cookie 解析器也已弃用。
https://simplapi.wordpress.com/2012/04/13/php-and-node-js-session-share-redi/
NodeJS + ExpressJS + RedisStore Session is undefined
如果有人可以发布一些更新的代码,那就太好了...
编辑 - 到目前为止节点服务器代码的摘录:
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server),
redis = require('redis'),
client = redis.createClient();
var session = require('express-session'),
RedisStore = require('connect-redis')(session);
app.get('/', function(req, res)
res.sendfile('/');
);
app.use(
session(
name: 'PHPSESSID'
store: new RedisStore(
prefix: 'PHPSESSID',
port: 6379
)
)
);
io.sockets.on('connection', function (socket)
app.use(function(req, res, next)
console.log(req.session);
);
.......
包:
├─┬ connect@2.17.1
│ ├── basic-auth-connect@1.0.0
│ ├─┬ body-parser@1.2.0
│ │ └─┬ raw-body@1.1.4
│ │ └── bytes@0.3.0
│ ├── bytes@1.0.0
│ ├─┬ compression@1.0.2
│ │ ├── bytes@0.3.0
│ │ ├── compressible@1.0.1
│ │ └── negotiator@0.4.3
│ ├── connect-timeout@1.1.0
│ ├── cookie@0.1.2
│ ├── cookie-parser@1.1.0
│ ├── cookie-signature@1.0.3
│ ├─┬ csurf@1.2.0
│ │ ├── scmp@0.0.3
│ │ └── uid2@0.0.3
│ ├── debug@0.8.1
│ ├── errorhandler@1.0.1
│ ├─┬ express-session@1.2.0
│ │ ├── buffer-crc32@0.2.1
│ │ ├── uid2@0.0.3
│ │ └── utils-merge@1.0.0
│ ├── fresh@0.2.2
│ ├─┬ method-override@1.0.1
│ │ └── methods@1.0.0
│ ├── morgan@1.1.1
│ ├─┬ multiparty@2.2.0
│ │ ├─┬ readable-stream@1.1.13-1
│ │ │ ├── core-util-is@1.0.1
│ │ │ ├── inherits@2.0.1
│ │ │ ├── isarray@0.0.1
│ │ │ └── string_decoder@0.10.25-1
│ │ └── stream-counter@0.2.0
│ ├── on-headers@0.0.0
│ ├── parseurl@1.0.1
│ ├── pause@0.0.1
│ ├── qs@0.6.6
│ ├── response-time@1.0.0
│ ├── serve-favicon@2.0.0
│ ├─┬ serve-index@1.0.3
│ │ ├── batch@0.5.0
│ │ └── negotiator@0.4.3
│ ├─┬ serve-static@1.1.0
│ │ └─┬ send@0.3.0
│ │ ├── buffer-crc32@0.2.1
│ │ ├── debug@0.8.0
│ │ ├── mime@1.2.11
│ │ └── range-parser@1.0.0
│ ├─┬ type-is@1.2.0
│ │ └── mime@1.2.11
│ └── vhost@1.0.0
├─┬ connect-redis@2.0.0
│ └── debug@0.8.1
├─┬ express@4.1.1
│ ├─┬ accepts@1.0.1
│ │ ├── mime@1.2.11
│ │ └── negotiator@0.4.3
│ ├── buffer-crc32@0.2.1
│ ├── cookie@0.1.2
│ ├── cookie-signature@1.0.3
│ ├── debug@0.8.1
│ ├── escape-html@1.0.1
│ ├── fresh@0.2.2
│ ├── merge-descriptors@0.0.2
│ ├── methods@0.1.0
│ ├── parseurl@1.0.1
│ ├── path-to-regexp@0.1.2
│ ├── qs@0.6.6
│ ├── range-parser@1.0.0
│ ├─┬ send@0.3.0
│ │ ├── debug@0.8.0
│ │ └── mime@1.2.11
│ ├── serve-static@1.1.0
│ ├─┬ type-is@1.1.0
│ │ └── mime@1.2.11
│ └── utils-merge@1.0.0
├─┬ express-session@1.2.0
│ ├── buffer-crc32@0.2.1
│ ├── cookie@0.1.2
│ ├── cookie-signature@1.0.3
│ ├── debug@0.8.1
│ ├── on-headers@0.0.0
│ ├── uid2@0.0.3
│ └── utils-merge@1.0.0
├─┬ mysql@2.2.0
│ ├── bignumber.js@1.3.0
│ ├─┬ readable-stream@1.1.13-1
│ │ ├── core-util-is@1.0.1
│ │ ├── inherits@2.0.1
│ │ ├── isarray@0.0.1
│ │ └── string_decoder@0.10.25-1
│ └── require-all@0.0.8
├── redis@0.10.2
└─┬ socket.io@0.9.16
├── base64id@0.1.0
├── policyfile@0.0.4
├── redis@0.7.3
└─┬ socket.io-client@0.9.16
├─┬ active-x-obfuscator@0.0.1
│ └── zeparser@0.0.5
├── uglify-js@1.2.5
├─┬ ws@0.4.31
│ ├── commander@0.6.1
│ ├── nan@0.3.2
│ ├── options@0.0.5
│ └── tinycolor@0.0.1
└── xmlhttprequest@1.4.2
【问题讨论】:
【参考方案1】:对于节点(和 Express 4.x):
从express-session 的示例开始,但改用connect-redis 作为会话存储。
示例代码:
var express = require('express'),
app = express(),
cookieParser = require('cookie-parser'),
session = require('express-session'),
RedisStore = require('connect-redis')(session);
app.use(express.static(__dirname + '/public'));
app.use(function(req, res, next)
if (req.url.indexOf('favicon') > -1)
return res.send(404);
next();
);
app.use(cookieParser());
app.use(session(
store: new RedisStore(
// this is the default prefix used by redis-session-php
prefix: 'session:php:'
),
// use the default PHP session cookie name
name: 'PHPSESSID',
secret: 'node.js rules'
));
app.use(function(req, res, next)
req.session.nodejs = 'Hello from node.js!';
res.send(JSON.stringify(req.session, null, ' '));
);
app.listen(8080);
对于 PHP:
使用像 redis-session-php 这样的 redis 会话处理程序。
示例代码:
<?php
// from https://github.com/TheDeveloper/redis-session-php
require('redis-session-php/redis-session.php');
RedisSession::start();
$_SESSION["php"] = "Hello from PHP";
// `cookie` is needed by express-session to store information
// about the session cookie
if (!isset($_SESSION["cookie"]))
$_SESSION["cookie"] = array();
var_dump($_SESSION);
?>
注意:确保使用相同的prefix
(connect-redis)/REDIS_SESSION_PREFIX
(redis-session-php)(connect-redis 使用 'sess:' 和 redis-session-php 使用 'session:php :' 默认情况下)和ttl
(connect-redis)/session.gc_maxlifetime
(PHP) (如果您使用非默认的 redis 数据库,则使用相同的数据库)用于 redis-session-php 和 connect-redis。
【讨论】:
我的 php 代码库使用PHPSESSID
作为会话密钥。所以我将REDIS_SESSION_PREFIX
定义为PHPSESSID
。那是对的吗?另外,我不确定如何访问节点文件中的会话值。我将我的代码添加到上面的原始问题中。
不,前缀是redis特有的选项。那是用于键的前缀。如果您使用 PHP 的 cookie 名称 (PHPSESSID),则需要在您的 express-session 选项中设置 name: 'PHPSESSID'
。
我似乎仍然无法访问会话。
我想我可以安装 express 3 而不是 4,但这似乎是一个倒退..
我已经添加了我亲自测试并验证可以正常工作的示例代码。只需在浏览器中访问 PHP 和节点脚本,您应该会看到双方的会话数据。【参考方案2】:
我只是想在这里提供一个不需要 redis 的替代解决方案,并且我已经使用了几年(从另一个答案交叉发布):
这需要以下内容:
npm install cookie
npm install php-unserialize
此解决方案使用机器上的会话文件 - 您不必更改此行。
session.save_handler = files
^ 在你的 php.ini 文件中应该是这样的(默认)。
这是获取会话数据的超级简单代码:
var cookie = require('cookie');
var fs = require('fs');
var phpUnserialize = require('php-unserialize');
//This should point to your php session directory.
//My php.ini says session.save_path = "$US_ROOTF/tmp"
var SESS_PATH = "C:/SomeDirectory/WhereYourPHPIs/tmp/";
io.on('connection', function(socket)
//I just check if cookies are a string - may be better method
if(typeof socket.handshake.headers.cookie === "string")
var sid = cookie.parse(socket.handshake.headers.cookie);
if(typeof sid.PHPSESSID === "undefined")
console.log("Undefined PHPSESSID");
else
console.log("PHP Session ID: " + sid.PHPSESSID);
fs.readFile(SESS_PATH + "sess_" + sid.PHPSESSID, 'utf-8', function(err,data)
if(!err)
console.log("Session Data:");
var sd = phpUnserialize.unserializeSession(data);
console.log(sd);
else
console.log(err);
);
结果:
Authenticate user for socket.io/nodejs
【讨论】:
以上是关于在 php 和 node 之间共享会话的主要内容,如果未能解决你的问题,请参考以下文章