Reputation: 427
I'm writing a NodeJS solution which relies on Passport for authorisation and SocketIO.
When a socket connection is accessed I want to be able to fetch the users session/profile which is stored in MongoDB if there is one. (Through connect-mongo).
I have implemented Passport.socketio to access this from the Store.
io.set('authorization', passportSocketIo.authorize({
passport: require('passport'),
cookieParser: cookieParser,
key: 'connect.sid',
secret: 'StackSecret',
store: new store({
db: mongoose.connection.db,
collection: 'sessions',
}),
fail: FailedMethod
}));
I can then access the user's profile from "socket.handshake.user"..
socket.on("callback", function(){
console.log(socket.handshake.user); //Fetch Logged in user's Id
})
This would work perfectly if I was trying to block access to the socket but I want it to be open to every connection (Both with a session or not). I just want to be able to access their Passport session Id if they are logged in.
What is my best way of accessing a sessions userId from SocketIo?
I'm hoping Passport.socketio is overkill and I can do it easily without it.
Upvotes: 0
Views: 995
Reputation: 10082
Your own answer would probably suffice for this case, but you answered a more general question (how to access session info for a socket connection). The following is how I do it generally. Additionally, I normally register all the routes in such a way that they get a reference to a config, so I can also provide every request handler with a socket connection specific to this particular session:
var cookie = require("cookie"),
parseSignedCookie = require('connect').utils.parseSignedCookie;
var io = require('socket.io').listen(httpServer);
io.sockets.on("connection", function(socket) {
if (socket.handshake.headers.cookie) {
var cks = cookie.parse(socket.handshake.headers.cookie);
var sessionId = parseSignedCookie(cks["connect.sid"], config.sessionSecret);
config.sessionStore.get(sessionId, function(err, session) {
if (!err) {
console.info("connected socket for ID " + sessionId);
config[sessionId] = socket; // set socket to config so that request handlers could emit on it
socket.on("disconnect", function() {
console.info("disconnected socket for ID " + sessionId);
delete config[sessionId];
});
}
});
}
});
For the request handlers to know about the config I write them normally in the following form:
exports.get = function(conn, config) {
return function(req, res, next) {
var socket = config[request.sessionID];
if (socket) {
// socket.emit
}
res.end();
}
}
app.get("/", someModule.get(customConnection, config));
For the latter, see more under https://github.com/codelab-io/node-route-dir
Upvotes: 2
Reputation: 427
I like the fact that posting a question often helps you answer it!
The fail Method takes 4 parameters data, message, error, callback.
You can fire the call back with a success true and it will continue without authorisation.
function onAuthorizeFail(data, message, error, accept){
accept(null, true);
};
Upvotes: 0