Goal
What I want to do:
socket.io
)passport.js
to authenticate the login and socket
sessions.Notes
I have installed MongoStore
and passport.socket.io npm's
. I can login and set the cookie
of the user logged in (connect.sid
)
QUESTION
How do I setup the system to store socket
sessions and couple them with the session
of the user?
Code
app.js
/* The usual express setup */
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
User = require('./models/user.js'),
MongoStore = require('connect-mongo')(express);
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({
secret: 'chuck norris',
store: new MongoStore({db: User.name}, // the db's name
function(err) {
console.log(err || 'connect ok!');
})
}));
app.use(express.methodOverride());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.js (the passport part)
passport.use(new LocalStrategy({
usernameField: 'username',
passwordField: 'password'
},
function(username, password, done) {
User.findOne({username: username}, function(err, user) {
if(!user) {
return done(null, false, {message: 'Incorrect Username!'});
}
if(!user.validPassword(password)) {
return done(null, false, {message: 'Incorrect Password!'});
}
return done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
app.post('/',
passport.authenticate('local'),
function(req, res) {
res.redirect('/home/'+req.user.username);
});
app.js (socket.io part)
io.set('authorization', passportSocket.authorize({
key: 'connect.sid',
secret: 'chuck norris',
store: /* Not entirely sure what goes here */
fail : function(data, accept) { accept(null, false); },
success: function(data, accept) { accept(null, true); }
}));
io.sockets.on('connection', function(socket) {
console.log('User Connected: ' + socket.handshake.user.username);
});
You store your new memory story object instance into a variable and pass it in to both express and socket io like so. (be aware that we are using different stores but in theory it should not matter what store you use as long as you pass off control the proper way)...
var ...
,MemoryStore = express.session.MemoryStore
,sessionStore = new MemoryStore();
then in app.configure you...
app.use(express.session({store:sessionStore,secret:'secret',key:'express.sid'}));
and finally in socket.io configure
io.configure(function (){
io.set("authorization", passportSocketIo.authorize({
key: 'express.sid', //the cookie where express (or connect) stores its session id.
secret: 'secret', //the session secret to parse the cookie
store: sessionStore, //the session store that express uses
fail: function(data, accept) {
// console.log("failed");
// console.log(data);// *optional* callbacks on success or fail
accept(null, false); // second param takes boolean on whether or not to allow handshake
},
success: function(data, accept) {
// console.log("success socket.io auth");
// console.log(data);
accept(null, true);
}
}));
If you have done this correctly and your user successfully authenticates you should then be able to access the session data on the handshake object.
console.log(socket.handshake.user.username);
//or sometimes it might be...
console.log(socket.handshake.user[0].username);
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With