In node.js and express, there are many examples showing how to get session data.
- Node.js and Socket.io
- Express and Socket.io - Tying it all Together
- Socket.io and Session?
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){ ... });
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
- connect issue#588
- socket.io and express 3
- session.socket.io module
- socket.io-express library
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);
});
Your questions:
- How can I update/change a cookie through RedisStore?
- 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:
- Typically, you have exactly one cookie, which is the session id
- All user-state is stored on the server in a "session" which can be found via the session id
- You can use Redis as your back-end storage for your session data.
- Redis will allow you to keep session state, even when your server is restarted (good thing)
- You can store a mountain of data in your session (req.session.key = value)
- 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:
- Your second issue us about sessions without cookies. This is possible.
- You, basically, put the session id on the url of every request you send to the server.
- I strongly believe that most people allow cookies.
- If this is a requirement, google: "session without cookies"
Session data is available with:
req.session