express-session在使用socket.io时不设置会话cookie [英] express-session isn't setting session cookie while using with socket.io

查看:507
本文介绍了express-session在使用socket.io时不设置会话cookie的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用socket.io实现身份验证和会话。



经过大量研究 1 使用express和express-session。



问题是,express和socket.io连接似乎有不同的会话,因为<$ c



此外,在我的应用程序的浏览器中没有设置cookie(这可能是为什么两个组件都在创建不同的会话?)



我使用express 4.13.3 express-session 1.12.1 和socket.io 1.3.7



是我设置的服务器端代码:

  var app = require('express')(); 
var server = app.listen(80);
var parser = require('body-parser');
var Session = require('express-session');
var io = require('socket.io')(server);
var game = require('./ game.js');
var session = Session({
secret:'some secret',
resave:false,
saveUninitialized:false,
cookie:{
'name ':'test',
httpOnly:false,
secure:false,
maxAge:((60 * 1000)* 60)
}
}
app.use(parser.urlencoded({
extended:false
}));
app.use(session);
app.use(function(req,res,next){
res.header(Access-Control-Allow-Origin,*);
res.header - 控制允许标头,原点,请求的X,请求的内容类型,接受);
next();
});
app.post('/ login',function(req,res){
console.log('login%s',req.session.id);
console.dir .session,{
color:true
});
res.json({
status:'success'
});
});
io.use(function(socket,next){
session(socket.handshake,{},next);
});
console.log('socket server started @%s!',80);
io.on('connection',function(socket){
console.log('user connected%s',socket.handshake.session.id);
console.dir .handshake.session,{
color:true
});
socket.on('disconnect',function(){
console.log('user disconnected');
console.dir(socket.handshake.session,{
color:true
});
});
});

以及用于测试目的的客户代码:

  $。ajax({
url:'http://127.0.0.1:80/login',
type:'post',
success:function(response){
var socket = io('http://127.0.0.1:80');
}
});

以下是控制台中的输出:



这是资源部分浏览器:



我甚至困惑,因为 session 对象没有任何 id 属性,但 session.id 打印不同的值。也许这是来自对象原型链或某事。



我可以想到的我的代码和教程的唯一区别是,他们都服务 index.html 页面。



我已经读过某个地方,在这种情况下,我必须发送一个 http 请求在建立socket.io连接之前表达。



socket.io.js 客户端库是由express和socket.io共享的相同服务器提供的(< script src =http://127.0.0.1/socket.io/socket.io.js>< / script> ),除此之外,我还在建立套接字连接之前尝试了快速路由 / login p>

所以我想知道为什么在客户端没有设置cookie,为什么express和socket请求创建了不同的会话?我在这里失踪了什么?






1 代码主要基于:








PS:我想要做的是,当套接字客户端重新连接时,我需要把他带回会议的细节。我不想真的想快速分享会话,但明确的中间件是我遇到的唯一的方法来实现与socket.io的会话。

解决方案

这个问题与express或socket.io无关。



问题是,我从本地服务器加载项目other



因此,这是一个跨域的ajax请求,在这种情况下一些浏览器拒绝处理 Set-Cookie



我们可以通过添加

来解决这个问题。

  xhrFields:{
withCredentials:true
},

在此回答中提及的ajax选项



或者如果您're work with angular,sent {withCredentials:true} like



$ http {withCredentials:true,...})get(...),如本 answer



在服务器端,设置此标题:

  res.header(Access-Control-Allow-Credentials,'true'); 

如果添加,chrome将不允许使用通配符 * Access-Control-Allow-Origin 标头中。



  res.header(访问控制允许原始,允许的域); 


I'm trying to implement authentication and sessions with socket.io.

After a lot of research 1, I've set up the following which makes use of express and express-session.

The issue is that, express and socket.io connections seems to be having different sessions since the id I'm getting is different.

Also, no cookie is set in the browser from my application (which is possibly why both components are creating different sessions?)

I'm using express 4.13.3 express-session 1.12.1 and socket.io 1.3.7.

Below is the server side code that I've set up:

var app = require('express')();
var server = app.listen(80);
var parser = require('body-parser');
var Session = require('express-session');
var io = require('socket.io')(server);
var game = require('./game.js');
var session = Session({
  secret: 'some secret',
  resave: false,
  saveUninitialized: false,
  cookie: {
    'name': 'test',
    httpOnly: false,
    secure: false,
    maxAge: ((60 * 1000) * 60)
  }
});
app.use(parser.urlencoded({
  extended: false
}));
app.use(session);
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
app.post('/login', function(req, res) {
  console.log('login %s', req.session.id);
  console.dir(req.session, {
    color: true
  });
  res.json({
    status: 'success'
  });
});
io.use(function(socket, next) {
  session(socket.handshake, {}, next);
});
console.log('socket server started @ %s !', 80);
io.on('connection', function(socket) {
  console.log('user connected %s', socket.handshake.session.id);
  console.dir(socket.handshake.session, {
    color: true
  });
  socket.on('disconnect', function() {
    console.log('user disconnected');
    console.dir(socket.handshake.session, {
      color: true
    });
  });
});

and the code at client for testing purpose:

$.ajax({
   url: 'http://127.0.0.1:80/login',
   type:'post',
   success: function(response) {
      var socket = io('http://127.0.0.1:80');
   }
});

Below is the output in console:

and this is the resources section in browser:

I'm even confused seeing that the session object is not having any id property when logged in console, but session.id prints different values. Maybe this is coming from the objects prototype chain or something.

The only difference I can think of with my code and the tutorials out there is that, they are all serving the index.html page from the same express server. In my case I've the file locally.

I've read somewhere that in such cases I must send an http request to express before establishing the socket.io connection.

The socket.io.js client side library is served from the same server which is shared by express and socket.io (<script src="http://127.0.0.1/socket.io/socket.io.js"></script>), apart from this I'm also hitting the express route /login for testing purpose before the socket connection is established.

So I'm wondering why no cookie is being set in client side, and Why the express and socket requests have created different sessions..? What am I missing here..?


1 The code is mostly based on:


P.S: What I'm trying to do is, when a socket client re-connects, I need to put him back to where he was with the session details. I don't really want to share sessions with express, but express middleware is the only way I've came across to implement sessions with socket.io.

解决方案

The problem had nothing to do with express or socket.io.

The issue is that, I was loading the project from a local server other than the express and socket.io server.

So it's a cross domain ajax request, in which case some browsers refuse to handle the Set-Cookie header.

We can fix this by adding

xhrFields: {
   withCredentials: true
},

in the ajax options as mentined in this answer

Or if you're working with angular, sent {withCredentials: true} like

$http({withCredentials: true, ...}).get(...) as mentioned in this answer.

At server side, set this header:

res.header("Access-Control-Allow-Credentials", 'true');

If you add that, chrome will not allow you to use wildcard * in the Access-Control-Allow-Origin header anymore.

You should also set it to specific allowed domains.

res.header("Access-Control-Allow-Origin", "allowed domains");

这篇关于express-session在使用socket.io时不设置会话cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆