I have tried so many things to be able to grab the express session variables inside the socket.io connection in Node.JS, but keep failing. I've noticed that whenever I use the session middleware the right session isn't used instead it created 3 other useless sessions (unless saveUninitialized: true, if false then it doesn't save it, but still it uses the wrong session of course).
I tried:
- Using cookie-parser.
- Storing session in file.
- express-socket.io-session.
- redis
- and a few other things that I can't remember anymore.
But it all comes down to one thing - the socket doesn't use the same session as the express request (req.session) instead it creates 3 other sessions and also keeps on creating new ones upon socket activity.
Setup of client socket.io inside App component:
componentWillMount() {
let socket = io("http://localhost:5000");
this.setState({socket});
socket.emit("test"); // This actually returns the correct session.
}
Example of the way I send AJAX in ReactJS:
fetch('http://localhost:5000/home/userinfo', {
method: 'GET',
credentials: 'include',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
}).then(function(response) {
return response.json();
}).then(function(data) {
if (data.login) {
self.setState({username: data.login});
}
else {
self.props.history.push("/login");
}
});
express session setup:
var sessionMiddleware = session({
store: new sessionFileStore({ path: './sessions' }),
secret: 'nothingspecial',
maxAge: new Date(Date.now() + 3600000),
resave: true,
saveUninitialized: false
});
app.use(sessionMiddleware);
socket.io connection:
const server = app.listen(port, () => console.log(`Listening on port ${port}`));
const io = require('socket.io').listen(server);
io.use(function(socket, next) {
sessionMiddleware(socket.handshake, {}, next);
});
io.on('connection', function(socket) {
console.log('a user connected');
socket.on('disconnect', function() {
console.log('user disconnected');
});
socket.on('test', function() {
console.log(socket.handshake.session);
// Returns different session than when using app.get and then req.session for example
});
});
Also some other app.use that might be worth posting here:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
Would gladly appreciate help as I've wasted so much time already trying to figure this out.
Edit: I noticed that upon page refresh when I socket.emit straight from where the connection is started (App component) it actually grabs the right session. I tried to create some functions inside the App component, but still when I pass the function into a different component and run the props function it creates a new session.
How I pass the socket:
<Route path="/home" render={(props) => <Home {...props} socket={this.state.socket} />} />