I am trying to access the session from sockets, but can't seem to make a connection. Without fail, authorization fails and I get the fail callback with the following message:
failed connection to socket.io: No session found
I will place all my code here so that it might be easier to spot what I'm doing wrong.
var express = require('express');
var app = express();
var http = require('http');
var socketio = require('socket.io')
var passportSocketIo = require('passport.socketio');
var port = process.env.PORT || 3000;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var server = http.createServer(app);
var io = socketio.listen(server);
var dbConfig = require('./config/database.js');
mongoose.connect(dbConfig.url);
var sessionStore = new MongoStore({ db: mongoose.connection.db });
require('./config/passport')(passport);
app.use(morgan('dev'));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.use(session({
key: 'connect.sid',
secret: 'secret',
store: sessionStore,
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(express.static(__dirname + '/public'));
require('./app/routes.js')(app, passport);
server.listen(3000, function() {
console.log('App running on port: ' + port);
});
io.use(passportSocketIo.authorize({
passport: passport,
cookieParser: cookieParser,
key: 'connect.sid',
secret: 'secret',
store: sessionStore,
success: onAuthorizeSuccess,
fail: onAuthorizeFail
}));
function onAuthorizeSuccess(data, accept){
console.log('successful connection to socket.io');
accept(null, true);
}
function onAuthorizeFail(data, message, error, accept){
if(error)
throw new Error(message);
console.log('failed connection to socket.io:', message);
accept(null, false);
}
io.sockets.on('connection', function(socket) {
var date = new Date();
var time = date.getHours() + ":" + date.getMinutes();
socket.emit('message', {username: 'Server', message: 'welcome to the chat'});
socket.on('send', function(data) {
io.sockets.emit('message', data);
});
});
How should I be establishing a connection to the session with socket.io?
Also, I have seen that the user data is accessed via socket.handshake.user
. Would that be correct in this case?
And for clarity, the versions are as follows:
express: 4.8.5
passport: 0.2.0
socket.io: 1.0.6
passport.socketio: 3.2.0
EDIT
It appears that part of the issue was the localhost
versus 127.0.0.1
bug that already exists. However, now I don't get any handshake data back.
I had the exact same problem. For me the solution was not in the web server but due to calling localhost in the browser. Changing to 127.0.0.1 or to my acctual IP made life much happier.
See also answer and comments to: Javascript document.cookie always empty string
passport.socketio doesn't work with the new version of socket.io.
You should be able to remove passport.socketio and replace your current
io.use
with this one :First off, as I had noted in my question edit, be sure to type in the IP directly, rather than using
localhost
:127.0.0.1
. This is a known bug that will not allow you to send the cookie over correctly when pointing tolocalhost
.The passport-socketio Github page was, at last, updated with the following for the authorization callbacks for socket.io 1.x.
Also, the handshake data is no longer stored in the same place. Replace
socket.handshake.user
withsocket.request.user
.Ther is my full code: express, mongoDB session store, socket.io, passport-local, passport.socketio:
package.json
server.js
The passport.socketio package works with previous version of socket.io. At least this code works with socket.io v0.9.17 - https://github.com/vodolaz095/hunt/blob/v_0_2_x/lib/http/socket.io.js