在节点js中不可见php会话(redis)
我使用Redis服务器在Php和Node js之间共享会话。对于节点js客户端,使用“连接redis”,对于php客户端,使用redis会话php和Predis。我把大部分代码从这里升级到了(正确答案) app.js在节点js中不可见php会话(redis),php,node.js,session,Php,Node.js,Session,我使用Redis服务器在Php和Node js之间共享会话。对于节点js客户端,使用“连接redis”,对于php客户端,使用redis会话php和Predis。我把大部分代码从这里升级到了(正确答案) app.js var express = require('express'), app = express(), cookieParser = require('cookie-parser'), session = require('express-session'),
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'))
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',
resave: false,
saveUninitialized: false
}));
app.use(function(req, res, next) {
req.session.nodejs = 'Hello from node.js!';
res.send('<pre>' + JSON.stringify(req.session, null, ' ') + '</pre>');
});
app.listen(8080);
<?php
include 'redis.php';
session_start();
echo '<pre>';
var_dump($_COOKIE);
echo '</pre>';
echo '$_SESSION["nodejs"] = '.$_SESSION[selfId].'<br>';
$_SESSION[selfId] = 2;
echo '$_SESSION["nodejs"] = '.$_SESSION[selfId].'<br>';
?>
结果节点js页面()
您可能面临跨域问题。如果您使用不同于PHP的地址或端口运行PHP和节点(很可能是这样),HTML将不会在发送到另一个域的请求之间共享cookie,它将保留到每个域的单独副本 如果您正在使用子域(例如,URL中的PHP(如app1.mydomain.com)和运行在app2.mydomain.com中的NodeJ),您可以共享cookie,并使用主域cookie路径(mydomain.com)将其配置为设置/读取 这里有关于这个主题的好信息:
如果您需要更多信息,或者您的问题并非如此,请与我们联系。我通过本文解决此问题: app.js
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'))
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',
resave: false,
saveUninitialized: false
}));
app.use(function(req, res, next) {
req.session.nodejs = 'Hello from node.js!';
res.send('<pre>' + JSON.stringify(req.session, null, ' ') + '</pre>');
});
app.listen(8080);
<?php
include 'redis.php';
session_start();
echo '<pre>';
var_dump($_COOKIE);
echo '</pre>';
echo '$_SESSION["nodejs"] = '.$_SESSION[selfId].'<br>';
$_SESSION[selfId] = 2;
echo '$_SESSION["nodejs"] = '.$_SESSION[selfId].'<br>';
?>
cookie.js
<?php
//First we load the Predis autoloader
//echo dirname(__FILE__)."/predis-1.0/src/Autoloader.php";
require(dirname(__FILE__)."/redis-session-php/modules/predis/src/Autoloader.php");
//Registering Predis system
Predis\Autoloader::register();
/**
* redisSessionHandler class
* @class redisSessionHandler
* @file redisSessionHandler.class.php
* @brief This class is used to store session data with redis, it store in json the session to be used more easily in Node.JS
* @version 0.1
* @date 2012-04-11
* @author deisss
* @licence LGPLv3
*
* This class is used to store session data with redis, it store in json the session to be used more easily in Node.JS
*/
class redisSessionHandler{
private $host = "127.0.0.1";
private $port = 6379;
private $lifetime = 0;
private $redis = null;
/**
* Constructor
*/
public function __construct(){
$this->redis = new Predis\Client(array(
"scheme" => "tcp",
"host" => $this->host,
"port" => $this->port
));
session_set_save_handler(
array(&$this, "open"),
array(&$this, "close"),
array(&$this, "read"),
array(&$this, "write"),
array(&$this, "destroy"),
array(&$this, "gc")
);
}
/**
* Destructor
*/
public function __destruct(){
session_write_close();
$this->redis->disconnect();
}
/**
* Open the session handler, set the lifetime ot session.gc_maxlifetime
* @return boolean True if everything succeed
*/
public function open(){
$this->lifetime = ini_get('session.gc_maxlifetime');
return true;
}
/**
* Read the id
* @param string $id The SESSID to search for
* @return string The session saved previously
*/
public function read($id){
$tmp = $_SESSION;
$_SESSION = json_decode($this->redis->get("sessions/{$id}"), true);
if(isset($_SESSION) && !empty($_SESSION) && $_SESSION != null){
$new_data = session_encode();
$_SESSION = $tmp;
return $new_data;
}else{
return "";
}
}
/**
* Write the session data, convert to json before storing
* @param string $id The SESSID to save
* @param string $data The data to store, already serialized by PHP
* @return boolean True if redis was able to write the session data
*/
public function write($id, $data){
$tmp = $_SESSION;
session_decode($data);
$new_data = $_SESSION;
$_SESSION = $tmp;
$this->redis->set("sessions/{$id}", json_encode($new_data));
$this->redis->expire("sessions/{$id}", $this->lifetime);
return true;
}
/**
* Delete object in session
* @param string $id The SESSID to delete
* @return boolean True if redis was able delete session data
*/
public function destroy($id){
return $this->redis->delete("sessions/{$id}");
}
/**
* Close gc
* @return boolean Always true
*/
public function gc(){
return true;
}
/**
* Close session
* @return boolean Always true
*/
public function close(){
return true;
}
}
new redisSessionHandler();
?>
//直接向系统发送cookie,如果是node.js处理程序,则发送:
//request.headers.cookie
//如果是socket.io cookie,则发送:
//client.request.headers.cookie
module.exports.cookie=函数(co){
this.cookies={};
co&&co.split(“;”).forEach(函数(cookie){
var parts=cookie.split('=');
this.cookies[parts[0].trim()]=(parts[1]||''.trim();
}.约束(这个);
//检索所有可用的cookies
this.list=函数(){
把这个还给我;
};
//检索键/值对
this.get=函数(键){
如果(此.cookies[键]){
返回此。cookies[键];
}否则{
返回{};
}
};
//检索键/值对的列表
this.getList=函数(映射){
var cookieRet={};
对于(var i=0;i
redis.php
我在apache服务器(端口80)和同一域(端口443)中的node js服务器上使用相同的domain.php。它们位于不同的端口(一个是80,另一个是443),如果任何平台(php或节点)设置了cookie的port参数,它们将不会被视为生活在同一个域中(至少对于您的浏览器而言)。但我认为在您的情况下还有一个问题:一个是HTTP,另一个是HTTPS。在不安全和安全连接之间共享cookie需要在您的代码中进行额外配置(并且会使您的应用程序更易受攻击)。还有一件事:如果您使用localhost调用一个URL,而另一个使用127.0.0.1调用,则它们不会共享相同的cookie。正如您所看到的,需要跟踪问题
//Directly send cookie to system, if it's node.js handler, send :
//request.headers.cookie
//If it's socket.io cookie, send :
//client.request.headers.cookie
module.exports.cookie = function(co){
this.cookies = {};
co && co.split(';').forEach(function(cookie){
var parts = cookie.split('=');
this.cookies[parts[0].trim()] = (parts[1] || '').trim();
}.bind(this));
//Retrieve all cookies available
this.list = function(){
return this.cookies;
};
//Retrieve a key/value pair
this.get = function(key){
if(this.cookies[key]){
return this.cookies[key];
}else{
return {};
}
};
//Retrieve a list of key/value pair
this.getList = function(map){
var cookieRet = {};
for(var i=0; i<map.length; i++){
if(this.cookies[map[i]]){
cookieRet[map[i]] = this.cookies[map[i]];
}
}
return cookieRet;
};
};
<?php
include 'redis.php';
session_start();
echo '<pre>';
var_dump($_COOKIE);
echo '</pre>';
echo '$_SESSION["nodejs"] = '.$_SESSION[selfId].'<br>';
$_SESSION[selfId] = 2;
echo '$_SESSION["nodejs"] = '.$_SESSION[selfId].'<br>';
?>
<?php
//First we load the Predis autoloader
//echo dirname(__FILE__)."/predis-1.0/src/Autoloader.php";
require(dirname(__FILE__)."/redis-session-php/modules/predis/src/Autoloader.php");
//Registering Predis system
Predis\Autoloader::register();
/**
* redisSessionHandler class
* @class redisSessionHandler
* @file redisSessionHandler.class.php
* @brief This class is used to store session data with redis, it store in json the session to be used more easily in Node.JS
* @version 0.1
* @date 2012-04-11
* @author deisss
* @licence LGPLv3
*
* This class is used to store session data with redis, it store in json the session to be used more easily in Node.JS
*/
class redisSessionHandler{
private $host = "127.0.0.1";
private $port = 6379;
private $lifetime = 0;
private $redis = null;
/**
* Constructor
*/
public function __construct(){
$this->redis = new Predis\Client(array(
"scheme" => "tcp",
"host" => $this->host,
"port" => $this->port
));
session_set_save_handler(
array(&$this, "open"),
array(&$this, "close"),
array(&$this, "read"),
array(&$this, "write"),
array(&$this, "destroy"),
array(&$this, "gc")
);
}
/**
* Destructor
*/
public function __destruct(){
session_write_close();
$this->redis->disconnect();
}
/**
* Open the session handler, set the lifetime ot session.gc_maxlifetime
* @return boolean True if everything succeed
*/
public function open(){
$this->lifetime = ini_get('session.gc_maxlifetime');
return true;
}
/**
* Read the id
* @param string $id The SESSID to search for
* @return string The session saved previously
*/
public function read($id){
$tmp = $_SESSION;
$_SESSION = json_decode($this->redis->get("sessions/{$id}"), true);
if(isset($_SESSION) && !empty($_SESSION) && $_SESSION != null){
$new_data = session_encode();
$_SESSION = $tmp;
return $new_data;
}else{
return "";
}
}
/**
* Write the session data, convert to json before storing
* @param string $id The SESSID to save
* @param string $data The data to store, already serialized by PHP
* @return boolean True if redis was able to write the session data
*/
public function write($id, $data){
$tmp = $_SESSION;
session_decode($data);
$new_data = $_SESSION;
$_SESSION = $tmp;
$this->redis->set("sessions/{$id}", json_encode($new_data));
$this->redis->expire("sessions/{$id}", $this->lifetime);
return true;
}
/**
* Delete object in session
* @param string $id The SESSID to delete
* @return boolean True if redis was able delete session data
*/
public function destroy($id){
return $this->redis->delete("sessions/{$id}");
}
/**
* Close gc
* @return boolean Always true
*/
public function gc(){
return true;
}
/**
* Close session
* @return boolean Always true
*/
public function close(){
return true;
}
}
new redisSessionHandler();
?>