Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
socket.io in Express 3
var express = require('express')
, http = require('http')
, connect = require('connect')
, io = require('socket.io');
var app = express();
/* NOTE: We'll need to refer to the sessionStore container later. To
* accomplish this, we'll create our own and pass it to Express
* rather than letting it create its own. */
var sessionStore = new connect.session.MemoryStore();
/* NOTE: We'll need the site secret later too, so let's factor it out.
* The security implications of this are left to the reader. */
var SITE_SECRET = 'I am not wearing any pants';
/*
* ... skipping some of your app settings ...
*/
app.use(express.bodyParser());
/* NOTE: Pass the cookieParser the site secret. It used to be that
* express.session() got the secret, but in Express 3 that's
* no longer the case. */
app.use(express.cookieParser(SITE_SECRET);
/* NOTE: We'll need to know the key used to store the session, so
* we explicitly define what it should be. Also, we pass in
* our sessionStore container here. */
app.use(express.session({
key: 'express.sid'
, store: sessionStore
}));
/*
* ... skipping the rest of your app settings ...
*/
var server = http.createServer(app);
server.listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
/**
* Socket.io
*/
var sio = io.listen(server);
sio.set('authorization', function(data, accept){
/* NOTE: To detect which session this socket is associated with,
* we need to parse the cookies. */
if (!data.headers.cookie) {
return accept('Session cookie required.', false);
}
/* XXX: Here be hacks! Both of these methods are part of Connect's
* private API, meaning there's no guarantee they won't change
* even on minor revision changes. Be careful (but still
* use this code!) */
/* NOTE: First parse the cookies into a half-formed object. */
data.cookie = require('cookie').parseCookie(data.headers.cookie);
/* NOTE: Next, verify the signature of the session cookie. */
data.cookie = require('cookie').parseSignedCookies(data.cookie, SITE_SECRET);
/* NOTE: save ourselves a copy of the sessionID. */
data.sessionID = data.cookie['express.sid'];
/* NOTE: get the associated session for this ID. If it doesn't exist,
* then bail. */
sessionStore.get(data.sessionID, function(err, session){
if (err) {
return accept('Error in session store.', false);
} else if (!session) {
return accept('Session not found.', false);
}
// success! we're authenticated with a known session.
data.session = session;
return accept(null, true);
});
});
sio.sockets.on('connection', function(socket){
var hs = socket.handshake;
console.log('A socket with sessionID '+hs.sessionID+' connected.');
/* NOTE: At this point, you win. You can use hs.sessionID and
* hs.session. */
/* NOTE: This function could end here, and everything would be fine.
* However, I included this additional mechanism that Daniel
* added to keep the session alive by pinging it every 60
* seconds. I don't know how useful this is in the context of
* this demo, considering that the sessions aren't going to
* expire in the near future. So feel free to not include this: */
var intervalID = setInterval(function(){
hs.session.reload(function(){
hs.session.touch().save();
});
}, 60 * 1000);
socket.on('disconnect', function(){
console.log('A socket with sessionID '+hs.sessionID+' disconnected.');
clearInterval(intervalID);
});
});
@wiill

This comment has been minimized.

Show comment
Hide comment
@wiill

wiill Dec 28, 2012

Thanks mate, this is awesome tweak!

How would you do when using socket namespaces, i.e. the

sio.of('/namespace').authorization( function(data, accept){
   //...
});

-way...?

In my case, i finally had it worked, but now it appears my server isn't listening to any socket client-event anymore... (but clients seem to get all server-side event)

wiill commented Dec 28, 2012

Thanks mate, this is awesome tweak!

How would you do when using socket namespaces, i.e. the

sio.of('/namespace').authorization( function(data, accept){
   //...
});

-way...?

In my case, i finally had it worked, but now it appears my server isn't listening to any socket client-event anymore... (but clients seem to get all server-side event)

@wiill

This comment has been minimized.

Show comment
Hide comment
@wiill

wiill Dec 29, 2012

Ok, my bad, I was missing the client side impacts... from now it's

var socket = io.connect('http://' + window.location.host + '/namespace');

and after that as usual:

socket.on('connect', function(){
})

instead of the old way

        var sio = io.connect();
    var socket = sio.socket;
    socket.of('/namespace')

wiill commented Dec 29, 2012

Ok, my bad, I was missing the client side impacts... from now it's

var socket = io.connect('http://' + window.location.host + '/namespace');

and after that as usual:

socket.on('connect', function(){
})

instead of the old way

        var sio = io.connect();
    var socket = sio.socket;
    socket.of('/namespace')
@eephillip

This comment has been minimized.

Show comment
Hide comment
@eephillip

eephillip Dec 31, 2012

What versions of things are you using here, i'm running the latest and I show that the cookie module does't have a parseCookie or parsedSignedCookies method. I must be missing something?

I'm having all sorts of issues with the io authorization cookie. I send that to cookie.parse and node just crashes, and on stop of that it doesn't even give me an error stack dump.

What versions of things are you using here, i'm running the latest and I show that the cookie module does't have a parseCookie or parsedSignedCookies method. I must be missing something?

I'm having all sorts of issues with the io authorization cookie. I send that to cookie.parse and node just crashes, and on stop of that it doesn't even give me an error stack dump.

@johnsmith17th

This comment has been minimized.

Show comment
Hide comment
@johnsmith17th

johnsmith17th Mar 30, 2013

Excellent example! That is what I am looking for.

Excellent example! That is what I am looking for.

@benzmuircroft

This comment has been minimized.

Show comment
Hide comment
@benzmuircroft

benzmuircroft Apr 29, 2013

could not get this to work by copy and paste, data.headers.cookie=undefined in 'authorization'

could not get this to work by copy and paste, data.headers.cookie=undefined in 'authorization'

@wcamarao

This comment has been minimized.

Show comment
Hide comment
@wcamarao

wcamarao Aug 16, 2013

hey bob and everyone, would you try a tiny module I wrote for the same purpose as this gist?

feedback's appreciated.

https://github.com/wcamarao/session.socket.io

hey bob and everyone, would you try a tiny module I wrote for the same purpose as this gist?

feedback's appreciated.

https://github.com/wcamarao/session.socket.io

@calderaro

This comment has been minimized.

Show comment
Hide comment
@calderaro

calderaro Nov 6, 2013

why have to pass the secret to the cookieparser instead of the session?

why have to pass the secret to the cookieparser instead of the session?

@calderaro

This comment has been minimized.

Show comment
Hide comment
@calderaro

calderaro Nov 6, 2013

and how can i adapt it to a login system

and how can i adapt it to a login system

@jrode

This comment has been minimized.

Show comment
Hide comment
@jrode

jrode Dec 9, 2013

@wcamarao nice work, you rule.

jrode commented Dec 9, 2013

@wcamarao nice work, you rule.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment