Authentication methods over sockets
node.js, passport.js, sails.js, socket.io, sockets
Solution
Thanks to Kasper Isager there will be a passport generator for sails.js in the near future (Sails.js Version 0.10).
He implement Passport by using policies (sails middleware).
api/services/passport.js
var passport = require('passport');
passport.serializeUser(function(user, next) {
next(null, user.id);
});
passport.deserializeUser(function(id, next) {
User.findOne(id).done(next);
});
// Put your Passport config logic here
// Make passport globally available
module.exports = passport;
api/policies/passport.js
module.exports = function (req, res, next) {
// Initialize Passport
passport.initialize()(req, res, function () {
// Use the built-in sessions
passport.session()(req, res, function () {
// Make the user available throughout the frontend
res.locals.user = req.user;
next();
});
});
};
config/policies.js
module.exports.policies = {
'*': [ 'passport' ],
// MyCustomController: {
// update: [
// 'passport',
// 'authorize'
// ]
// }
};
This will make the the passport request methods (logIn, etc.) available in socket requests as well.
After a successful login your server-side session object will look like this:
{
// Express
cookie: {
originalMaxAge: null,
expires: null,
httpOnly: true,
path: '/'
},
// Passport
passport: {
user: '52fc98e108b31348a537fa43' // userId
}
}
You may access it in any policy with `req.session` or even on socket callbacks like:
config/sockets.js
onConnect: function(session, socket){}
onDisconnect: function(session, socket){}
If you want to see the Kaspers full implementation check out his repository: sails-generate-auth
Problem
I'm trying to get authentication working over sockets with `sailsjs` and `passport`. The challenge seems to be the fact that a socket connection doesn't have a session, and that sailsjs mocks a request object, causing it to not have Passport middleware setup. This caused nodejs to throw an error, saying that the `req` object didn't have a method called `logIn`. So, I've tried following the code snippet as provided by @xdissent here: Sails.js + Passport.js authentication through websockets which, indeed allows me to sign in without throwing errors. Or does it..? It turns out that it does something, But I have no idea what. Because upon fetching `req.user` through a different (socket) request, I get an empty object returned. I've looked in redis, too. This came out of it: ``` redis 127.0.0.1:6379> keys * 1) "waterline:broadcasting:_sequences:id" 2) "sess:aDJI0YHzh17E3AMjtKsZSijs" redis 127.0.0.1:6379> get "sess:aDJI0YHzh17E3AMjtKsZSijs" "{\"cookie\":{\"httpOnly\":true,\"path\":\"/\"}}" redis 127.0.0.1:6379> ``` So there is a session, just no user stored in it. So long story short, how do I get Passport and sailsjs to play nice over sockets. Update: I'd like some information about sessions, sockets and cookies with sails in general. So if I set stuff in a session, and refresh the browser, I'd like it to still be there. If I make an xhr call on the same page as the socket connection, shouldn't that be the same session?