I've seen a number of tutorials of how to share an express session with socket.io. However, they all usually show how to SET from express and then GET from within the socket connection. (server)
Is there a way to do this where you can SET from within the socket connection?
io.on('connection', function(socket){
socket.request.session.userdata = mydata;
});
I haven't played with socket.io in a long time but that sounds more like a question to ask the socket.io team. :smile:
addendum: why would you want to be able to _set_ from within the socket connection? the session should never be directly modifiable from the client's connection...
SET and GET server-side... just that I want to be able to SET from within the socket on the server...
server.js
express.get('/', function(req, res){
req.session.userid = 4;
});
io.on('connection', function(socket){
console.log(socket.request.session.userid)
// 4
console.log(socket.request.session.someothervar);
// undefined
socket.request.session.someothervar = 10;
});
var express = require('express')
var expressSession = require('express-session')
var http = require('http')
var io = require('socket.io')
var session = expressSession({ /* configuration */ })
// middleware
app.use(session)
// routes
app.get('/', function() {})
// setup servers
var server = http.createServer(app);
var sio = io.listen(server);
// setup socket auth with sessions
sio.set('authorization', function(handshake, accept) {
session(handshake, {}, function (err) {
if (err) return accept(err)
var session = socket.handshake.session;
// check the session is valid
accept(null, session.userid != null)
})
})
// setup socket connections to have the session on them
sio.sockets.on('connection', function (socket) {
session(socket.handshake, {}, function (err) {
if (err) { /* handle error */ }
var session = socket.handshake.session;
// do stuff
// alter session
session.userdata = mydata
// and save session
session.save(function (err) { /* handle error */ })
})
})
@dougwilson Thanks, the thing I was missing which is super obvious now that I know was...
session.save()
sigh.
Basically, if your socket.request.session in your example is our session object, you just need to call the .save() method on it.
Edit: ah, you just said the same thing :D
We could probably expand the https://github.com/expressjs/session#sessionsave section a bit more.
Hi I still cannot get your example code working with [email protected], [email protected]. The webpage always return to '/' after form is posted. Can anybody help me check where the problem is? Thanks.
var express = require('express');
var app = express();
var expressSession = require('express-session');
var http = require('http');
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
var records = [
{ id: 1, username: 'jack', password: 'secret', name: 'Jack'}
, { id: 2, username: 'jill', password: 'birthday', name: 'Jill'}
];
passport.use(new LocalStrategy(
function(username, password, cb) {
console.log("username="+username+" password="+password);
findByUsername(username, function(err, user) {
if (err) { console.log("err"); return cb(err); }
if (!user) { console.log("user not found"); return cb(null, false); }
if (user.password != password) { console.log("password not match"); return cb(null, false); }
console.log("login success");
return cb(null, user);
});
}
));
passport.serializeUser(function(user, cb) {
console.log("serializeUser="+JSON.stringify(user));
cb(null, user.id);
});
passport.deserializeUser(function(id, cb) {
console.log("deserializeUser="+id);
findById(id, function (err, user) {
if (err) { return cb(err); }
cb(null, user);
});
});
var session = expressSession({ resave:true, saveUninitialized: true, secret: 'my cat' })
// middleware
app.use(session)
app.use(passport.initialize());
app.use(passport.session());
// routes
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index1.html');
}).post('/login',
passport.authenticate('local', {failureRedirect: '/'}),
function(req, res){
res.sendFile(__dirname + '/home1.html');
}).get('/logout', function(req, res){
req.session.destroy(function(err) {
if(err) {
logger.error(err);
}
else {
res.redirect('/');
}
});
});
// setup servers
var server = app.listen(1337, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
var http = require('http').Server(app);
var io = require('socket.io')(http);
// setup socket auth with sessions
io.set('authorization', function(handshake, accept) {
session(handshake, {}, function (err) {
if (err) return accept(err)
var session = socket.handshake.session;
// check the session is valid
accept(null, session.userid != null)
})
})
// setup socket connections to have the session on them
io.sockets.on('connection', function (socket) {
session(socket.handshake, {}, function (err) {
if (err) { /* handle error */ }
var session = socket.handshake.session;
// do stuff
// alter session
session.userdata = mydata
// and save session
session.save(function (err) { /* handle error */ })
})
})
function findByUsername(username, cb)
{
for (var i = 0, len = records.length; i < len; i++) {
var record = records[i];
if (record.username === username) {
return cb(null, record);
}
}
return cb(null, null);
}
function findById(id, cb)
{
var idx = id - 1;
if (records[idx]) {
cb(null, records[idx]);
} else {
cb(new Error('User ' + id + ' does not exist'));
}
}
Funny, I actually had to read this post to do the opposite. My NodeJs controller /logout was being called but my socket.io middleware kept bringing the user session back to life. Had to get rid of session.touch.save() and now everything works great!
Most helpful comment