13

In node.js and express, there are many examples showing how to get session data.

As you can see when you visit the 3rd link, it's a link to StackOverflow. There was a good answer, but as pointed out in those comments by @UpTheCreek, connect no longer has the parseCookie method. I have just run into this problem as well. All of the tutorials I have found uses connect's parseCookie method which now doesn't exist. So I asked him how we can get the session data and he said he doesn't know the best approach so I thought I'd post the question here. When using express@3.0.0rc4, socket.io, and redis, how can we get session data and use that to authorize the user? I've been able to use require('connect').utils.parseSignedCookie;, but when I do that, I always get a warning/error when handshaking,

warn - handshake error Error

and from what I've read it sounds like that isn't a permanent solution anyways.


UPDATE

Ok I got session.socket.io working on my server. And as I suspected, I got stuck at the point of authorizing. I think I might be going about this the wrong way, so feel free to correct me. In my Redis database, I will have user's information. The first time that they login, I want to update their cookie so it contains their user information. Then the next time they come back to the site, I want to check if they have a cookie and if the user information is there. If it is not there, I want to send them to the login screen. At the login screen, when a user submits information, it would test that information against the Redis database, and if it matches, it would update the cookie with user information. My questions are these:

1) How can I update/change a cookie through RedisStore?

2) It looks like session data is saved only in cookies. How can I keep track of user information from page to page if someone has cookies turned off?

Here is my applicable code:

//...hiding unapplicable code...
var redis = require('socket.io/node_modules/redis');
var client = redis.createClient();
var RedisStore = require('connect-redis')(express);
var redis_store = new RedisStore();
var cookieParser = express.cookieParser('secret');

app.configure(function(){
  //...hiding unapplicable code...
  app.use(cookieParser);
  app.use(express.session({secret: 'secret', store: redis_store}));
});

//...hiding code that starts the server and socket.io

var SessionSockets = require('session.socket.io');
var ssockets = new SessionSockets(io, redis_store, cookieParser);

io.configure(function(){
  io.set('authorization', function(handshake, callback){
    if(handshake.headers.cookie){
      //var cookie = parseCookie(handshake.headers.cookie);
      //if(cookie.user){
      //  handshake.user = cookie.user;
      //}
    }
    callback(null, true);
  });
});

ssockets.on('connection', function(err, socket, session){ ... });
Community
  • 1
  • 1
Aust
  • 10,892
  • 11
  • 41
  • 70
  • Does this cover what you are looking for? http://stackoverflow.com/questions/11680997/socket-io-parse-connect-2-4-1-signed-session-cookie – Robert Peters Oct 11 '12 at 17:32
  • @RobertPeters - That looks promising. I'll have to play around with it after work and I'll let you know. – Aust Oct 11 '12 at 17:52
  • 1
    @RobertPeters - I looked over it, but I didn't have time to try and implement it haha. I think I'll be able to implement `session.socket.io` with `RedisStore` easy enough, but I will probably run into troubles when trying to access `Redis` when first authorizing. I'll post updates along the way. – Aust Oct 12 '12 at 21:00
  • For express 4 & socket.io 1.x http://stackoverflow.com/a/25618636/153718 – Epeli Sep 02 '14 at 10:49

4 Answers4

6

Have a look at socket.io's wiki. Especially the parts Configuring Socket.IO and Authorization and handshaking.

It shows how to use socket.io with a RedisStore and gives two different authorization methods.

More information about connecting express v3, redis and socket.io

zemirco
  • 15,163
  • 6
  • 56
  • 84
  • 1
    Yes I've looked at those, but it doesn't explain how to access information from `RedisStore`. For example, I want users to sign in with their e-mail and password, and then after they sign in use the session data to keep them signed in. So in the authorization, compare their input with the Redis database, and then if it is correct authorize them and add that to the `handshakeData` variable. So their example is just too vague for me. If you could show me an example of how to do that, you would be my hero haha. :) – Aust Oct 11 '12 at 15:22
  • added some more links that can help you – zemirco Oct 17 '12 at 10:40
  • The first 3 links simply point to socket.io github page and I couldn't find the sections you mentioned there... – T J Nov 25 '15 at 14:05
4

After switching to session.socket.io for a while I ran into a few problems due to the asynchronous nature of the module when loading the session information. So I ended up creating my own module called session.io. It is used like this:

var express = require('express');
var app = express();
var server = require('http').createServer(app);

//Setup cookie and session handlers
//Note: for sessionStore you can use any sessionStore module that has the .load() function
//but I personally use the module 'sessionstore' to handle my sessionStores.
var cookieParser = express.cookieParser('secret');
var sessionStore = require('sessionstore').createSessionStore();

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  //...truncate...//
  app.use(cookieParser);
  //make sure to use the same secret as you specified in your cookieParser
  app.use(express.session({secret: 'secret', store: sessionStore}));
  app.use(app.router);
});

app.get('/', function(req, res){
  res.send('<script src="/socket.io/socket.io.js"></script><script>io.connect();</script>Connected');
});

server.listen(app.get('port'), function(){
  console.log('Listening on port ' + app.get('port'));
});

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

io.configure(function(){
  //use session.io to get our session data
  io.set('authorization', require('session.io')(cookieParser, sessionStore));
});

io.on('connection', function(socket){
  //we now have access to our session data like so
  var session = socket.handshake.session;
  console.log(session);
});
Aust
  • 10,892
  • 11
  • 41
  • 70
2

Your questions:

  1. How can I update/change a cookie through RedisStore?
  2. It looks like session data is saved only in cookies. How can I keep track of user information from page to page if someone has cookies turned off?

Cookies / Sessions / RedisStore Thoughts:

  1. Typically, you have exactly one cookie, which is the session id
  2. All user-state is stored on the server in a "session" which can be found via the session id
  3. You can use Redis as your back-end storage for your session data.
  4. Redis will allow you to keep session state, even when your server is restarted (good thing)
  5. You can store a mountain of data in your session (req.session.key = value)
  6. All data stored in the session will be persistant until the user logs out, or their session expires

Example node.js Code:

var app = express.createServer(
  express.static(__dirname + '/public', { maxAge: 31557600000 }),
  express.cookieParser(),
    express.session({ secret: 'secret', store: new RedisStore({
          host: 'myredishost',
          port: 'port',
          pass: 'myredispass',
          db: 'dbname',
      }, cookie: { maxAge: 600000 })})
);

Session and Cookie Thoughts:

  1. Your second issue us about sessions without cookies. This is possible.
  2. You, basically, put the session id on the url of every request you send to the server.
  3. I strongly believe that most people allow cookies.
  4. If this is a requirement, google: "session without cookies"
DanBaker
  • 523
  • 4
  • 12
-2

Session data is available with:

req.session
chovy
  • 59,357
  • 43
  • 187
  • 234