Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在节点js中不可见php会话(redis)_Php_Node.js_Session - Fatal编程技术网

在节点js中不可见php会话(redis)

在节点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'),

我使用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'),
    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();
?>