node.js - Socket.io 通过 XHR-Polling 不传递 cookie

标签 node.js express socket.io nowjs-sockets

我正在尝试将 Express (3.x) 与 NowJS(主要是 Socket.io 的包装器)结合起来创建一个首先要求您登录的实时应用程序。我承认我对 Node 很陌生,但我对每个包如何单独工作有很好的了解。然而,从 NowJS 访问 Express Session 信息让我感到不舒服。

问题似乎是,由于我被迫使用 XHR-Polling(使用 Heroku 作为托管平台),我无法在 Socket.io 身份验证方法中轻松访问 cookie 信息。在下面的 authFunction 代码中,“data.headers.cookie”未定义。以一种迂回的方式(在 Now.js 代码中),这会在 nowjs.on("connect",...) 回调中将“this.user.cookie”留空(但不是未定义)。这反过来又使我无法获取 session 信息。

通过阅读,似乎 cookie 可能只有在使用 websocket 时才可用。如果没有 cookie,除了为他们生成的随机标识符之外,我不知道哪个用户正在调用服务器。

有人可以建议如何解决这个问题吗?在与 Now.js 服务器建立连接时,是否需要手动从客户端发送 cookie?

var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.engine('html', consolidate.swig);
  app.set('view engine', 'html');

  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser());
  app.use(express.session({ secret: "secrethere" , store: sessionStore}));

  app.use(express.static(path.join(__dirname, 'public')));
  app.use(app.router);
});

app.configure('development', function(){
  app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
});

//Map the routes
var routes = require('./routes/routes')(db);
app.get[...] //routes defined here

var server = http.createServer(app, {cookieKey: 'connect.sid'});
server.listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

var parseCookie = require('express/node_modules/connect').utils.parseCookie;
var authFunction = function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
    // if there is, parse the cookie
    data.cookie = parseCookie(data.headers.cookie);

    // note that you will need to use the same key to grad the
    // session id, as you specified in the Express setup.
    data.sessionID = data.cookie['connect.sid'];
} else {
   // if there isn't, turn down the connection with a message
   // and leave the function.
   return accept('No cookie transmitted.', false);
}

// accept the incoming connection
accept(null, true);
};

var everyone = nowjs.initialize(server, {socketio: {transports: ['xhr-polling', 'jsonp-polling'], authorization: authFunction}});

nowjs.on('connect', function (socket) {
//TODO - This will need to be based on the URL that is being visited, or
//similar to establish that users are viewing the same thing
var sid = unescape(this.user.cookie["connect.sid"]); //# you DO have to unescape the session id!

sessionStore.get(sid, function(err, sess){
    console.log("That group who joined? his userId is " + sess.userId)
});

var newRoom = "group";//this.user.session;//.groupName;
var newGroup = nowjs.getGroup(newRoom);
this.now.serverRoom = newRoom;
newGroup.addUser(this.user.clientId);
});

编辑:我当然更喜欢简单的解决方案,例如这里的最佳答案:Session support in Now.js ,但这对我不起作用(可能)出于同样的原因 - 我的“cookie”是空的并且不包含“connect.sid”键。

最佳答案

经过大量尝试不同的事情后,我意识到这实际上与我使用的环境(Cloud9 IDE)有关。

使用 Cloud9 进行调试时,它们会为您提供一个不错的 URL,用于浏览您的站点:“http://[projectname].[username].c9.io”。但是,NowJS 将其请求发送到“http://project-[unique ID].rhcloud.com/socket.io/1/xhr-polling/...”。这不会提示将 cookie 与请求一起发送,因为它与 cookie 关联的主机不是同一主机(好吧,这里的术语可能有点偏离)。

为了解决这个问题,我使用“http://project-[unique ID].rhcloud.com/...”作为调试基础,它似乎 100% 正常工作。 Heroku 似乎没有这个问题,因为所有请求(常规页面请求 socketio)都通过同一主机。

关于node.js - Socket.io 通过 XHR-Polling 不传递 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13522649/

相关文章:

javascript - 如何在 Slack channel 中发送私信?

node.js - 在平均堆栈应用程序中,req.body 为空

android - 当Android聊天应用程序处于后台时如何接收消息作为通知

javascript - 使用 Supertest 和模拟数据库进行 Express JS 集成测试

node.js - Socket.io 在服务器端丢失数据

javascript - 如何使用 Context API 将单个 Socket IO 实例传递给页面?

node.js - 如何在sequelize js中按外键查找数据?

node.js - Visual Studio Code - Node.js - 找不到名称 '__dirname'

node.js - 使用关联进行后续更新

node.js - 在另一个集合中保存新文档后,是否可以在回调函数中更新文档?