문제

I'm using express framework. I want to reach session data from socket.io. I tried express dynamicHelpers with client.listener.server.dynamicViewHelpers data, but i can't get session data. Is there a simple way to do this? Please see the code

app.listen(3000);

var io = require('socket.io');
var io = io.listen(app);

io.on('connection', function(client){
    // I want to use session data here
    client.on('message', function(message){
        // or here
    });
    client.on('disconnect', function(){
        // or here
    }); 
});
도움이 되었습니까?

해결책

This won't work for sockets going over the flashsocket transport (it doesn't send the server the needed cookies) but it reliably works for everything else. I just disable the flashsocket transport in my code.

To make it work, in the express/connect side, I explicitly define the session store so I can use it inside socket:

MemoryStore = require('connect/middleware/session/memory'),
var session_store = new MemoryStore();
app.configure(function () {
  app.use(express.session({ store: session_store }));
});

Then inside my socket code, I include the connect framework so I can use its cookie parsing to retrieve the connect.sid from the cookies. I then look up the session in the session store that has that connect.sid like so:

var connect = require('connect');
io.on('connection', function(socket_client) {
  var cookie_string = socket_client.request.headers.cookie;
  var parsed_cookies = connect.utils.parseCookie(cookie_string);
  var connect_sid = parsed_cookies['connect.sid'];
  if (connect_sid) {
    session_store.get(connect_sid, function (error, session) {
      //HOORAY NOW YOU'VE GOT THE SESSION OBJECT!!!!
    });
  }
});

You can then use the session as needed.

다른 팁

The Socket.IO-sessions module solution exposes the app to XSS attacks by exposing the session ID at the client (scripting) level.

Check this solution instead (for Socket.IO >= v0.7). See docs here.

I suggest not to entirely reinvent the wheel. The tools you need is already an npm package.I think this is what you need: session.socket.io I am using it in these days and it will be very helpful I guess!! Linking the express-session to the socket.io layer will have so many advantages!

Edit: After trying some modules that didn't work, I've actually gone and written my own library to do this. Shameless plug: go check it out at https://github.com/aviddiviner/Socket.IO-sessions. I'll leave my old post below for historical purposes:


I got this work quite neatly without having to bypass the flashsocket transport as per pr0zac's solution above. I am also using express with Socket.IO. Here's how.

First, pass the session ID to the view:

app.get('/', function(req,res){
  res.render('index.ejs', {
    locals: { 
      connect_sid: req.sessionID
      // ...
    }
  });
});

Then in your view, link it in with Socket.IO client-side:

<script>
  var sid = '<%= connect_sid %>';
  var socket = new io.Socket();
  socket.connect();
</script>
<input type="button" value="Ping" onclick="socket.send({sid:sid, msg:'ping'});"/>

Then in your server-side Socket.IO listener, pick it up and read/write the session data:

var socket = io.listen(app);
socket.on('connection', function(client){
  client.on('message', function(message){
    session_store.get(message.sid, function(error, session){
      session.pings = session.pings + 1 || 1;
      client.send("You have made " + session.pings + " pings.");
      session_store.set(message.sid, session);  // Save the session
    });
  });
});

In my case, my session_store is Redis, using the redis-connect library.

var RedisStore = require('connect-redis');
var session_store = new RedisStore;
// ...
app.use(express.session({ store: session_store }));

Hope this helps someone who finds this post while searching Google (as I did ;)

See this: Socket.IO Authentication

I would suggest not fetching anything via client.request... or client.listener... as that is not directly attached to the client object and always point to the last logged in user!

Check out Socket.IO-connect

Connect WebSocket Middleware Wrapper Around Socket.IO-node https://github.com/bnoguchi/Socket.IO-connect

This will allow you to push the Socket.IO request(s) down the Express/Connect middleware stack before handling it with Socket.IO event handlers, giving you access to the session, cookies, and more. Although, I'm not sure that it works with all of Socket.IO's transports.

You can make use of express-socket.io-session .

Share a cookie-based express-session middleware with socket.io. Works with express > 4.0.0 and socket.io > 1.0.0 and won't be backward compatible.

Worked for me!!

You can have a look at this: https://github.com/bmeck/session-web-sockets

or alternatively you can use:

io.on('connection', function(client) { 
  var session = client.listener.server.viewHelpers; 
  // use session here 
});

Hope this helps.

I am not sure that I am doing it right. https://github.com/LearnBoost/socket.io/wiki/Authorizing

With the handshake data, you can access to the cookies. And in the cookies, you can grab connect.sid which is the session id for each client. And then use the connect.sid to get the session data from database (I am assuming you are using RedisStore)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top