Socket.IO Authentication Socket.IO Authentication express express

Socket.IO Authentication


Use connect-redis and have redis as your session store for all authenticated users. Make sure on authentication you send the key (normally req.sessionID) to the client. Have the client store this key in a cookie.

On socket connect (or anytime later) fetch this key from the cookie and send it back to the server. Fetch the session information in redis using this key. (GET key)

Eg:

Server side (with redis as session store):

req.session.regenerate...res.send({rediskey: req.sessionID});

Client side:

//store the key in a cookieSetCookie('rediskey', <%= rediskey %>); //http://msdn.microsoft.com/en-us/library/ms533693(v=vs.85).aspx//then when socket is connected, fetch the rediskey from the document.cookie and send it back to servervar socket = new io.Socket();socket.on('connect', function() {  var rediskey = GetCookie('rediskey'); //http://msdn.microsoft.com/en-us/library/ms533693(v=vs.85).aspx  socket.send({rediskey: rediskey});});

Server side:

//in io.on('connection')io.on('connection', function(client) {  client.on('message', function(message) {    if(message.rediskey) {      //fetch session info from redis      redisclient.get(message.rediskey, function(e, c) {        client.user_logged_in = c.username;      });    }  });});


I also liked the way pusherapp does private channels.enter image description here

A unique socket id is generated and sent to the browser by Pusher. This is sent to your application (1) via an AJAX request which authorizes the user to access the channel against your existing authentication system. If successful your application returns an authorization string to the browser signed with you Pusher secret. This is sent to Pusher over the WebSocket, which completes the authorization (2) if the authorization string matches.

Because also socket.io has unique socket_id for every socket.

socket.on('connect', function() {        console.log(socket.transport.sessionid);});

They used signed authorization strings to authorize users.

I haven't yet mirrored this to socket.io, but I think it could be pretty interesting concept.


I know this is bit old, but for future readers in addition to the approach of parsing cookie and retrieving the session from the storage (eg. passport.socketio ) you might also consider a token based approach.

In this example I use JSON Web Tokens which are pretty standard. You have to give to the client page the token, in this example imagine an authentication endpoint that returns JWT:

var jwt = require('jsonwebtoken');// other requiresapp.post('/login', function (req, res) {  // TODO: validate the actual user user  var profile = {    first_name: 'John',    last_name: 'Doe',    email: 'john@doe.com',    id: 123  };  // we are sending the profile in the token  var token = jwt.sign(profile, jwtSecret, { expiresInMinutes: 60*5 });  res.json({token: token});});

Now, your socket.io server can be configured as follows:

var socketioJwt = require('socketio-jwt');var sio = socketIo.listen(server);sio.set('authorization', socketioJwt.authorize({  secret: jwtSecret,  handshake: true}));sio.sockets  .on('connection', function (socket) {     console.log(socket.handshake.decoded_token.email, 'has joined');     //socket.on('event');  });

The socket.io-jwt middleware expects the token in a query string, so from the client you only have to attach it when connecting:

var socket = io.connect('', {  query: 'token=' + token});

I wrote a more detailed explanation about this method and cookies here.