Reputation: 11
https://github.com/xpepermint/socket.io-express-session This is one of many ways i tried. I tried all of these answers as well: How to share sessions with Socket.IO 1.x and Express 4.x? And some more...It all gives me the exaclty same result:
throw new TypeError("Parameter 'url' must be a string, not " + typeof url) ^ TypeError: Parameter 'url' must be a string, not undefined
I already tried every solution i found on the internet, basically everything leads me to the same error. At some point i simply tried copying and pasting examples found and they give me the exactly same results. I guess something went wrong after one of the middleware updates. How to fix it? Is there another, reliable way to share express session with socket.io?
var Session = require('express-session');
var session = Session({ secret: 'pass', resave: true, saveUninitialized: true });
var cookieParser = require('cookie-parser');
var express = require('express');
var app = express();
app.use(cookieParser());
app.use(session); // session support
app.get('/', function (req, res) {
req.session.uid = 1;
res.send('Hi user #' + req.session.uid);
});
var http = require('http').createServer(app);
http.listen(3000, function(){
console.log('listening on *:3000');
});
var ios = require('socket.io-express-session');
var io = require('socket.io')(http);
io.use(ios(session)); // session support
io.on('connection', function(socket){
console.log(socket.handshake.session);
});
Above is an example returning exactly this error.
Upvotes: 1
Views: 3065
Reputation: 488
Using Bradley Lederholz's answer, this is how I made it work for myself. Please refer to Bradley Lederholz's answer, for more explanation.
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io');
var cookieParse = require('cookie-parser')();
var passport = require('passport');
var passportInit = passport.initialize();
var passportSession = passport.session();
var session = require('express-session');
var mongoStore = require('connect-mongo')(session);
var mongoose = require('mongoose');
var sessionMiddleware = session({
secret: 'some secret',
key: 'express.sid',
resave: true,
httpOnly: true,
secure: true,
ephemeral: true,
saveUninitialized: true,
cookie: {},
store:new mongoStore({
mongooseConnection: mongoose.connection,
db: 'mydb'
});
});
app.use(sessionMiddleware);
io = io(server);
io.use(function(socket, next){
socket.client.request.originalUrl = socket.client.request.url;
cookieParse(socket.client.request, socket.client.request.res, next);
});
io.use(function(socket, next){
socket.client.request.originalUrl = socket.client.request.url;
sessionMiddleware(socket.client.request, socket.client.request.res, next);
});
io.use(function(socket, next){
passportInit(socket.client.request, socket.client.request.res, next);
});
io.use(function(socket, next){
passportSession(socket.client.request, socket.client.request.res, next);
});
io.on('connection', function(socket){
...
});
...
server.listen(8000);
Upvotes: 1
Reputation: 73
The error occurs in the stage when you use io.use(...)
The problem is that session middle ware expects to find the session in req.orginalUrl. A socket does not have an orginalUrl. To fix this, simply assign one...
io.use(function(socket, next){
socket.request.originalUrl = socket.request.url;
session(socket.request, socket.request.res, next);
});
The next problem is going to be that session(...) expects the cookies to be parsed. We can use 'cookie-parser' for this:
var cookieParse = cookieParser();
io.use(function(socket, next){
cookieParse(socket.request, socket.request.res, next);
});
After that we can simply bridge passport and socket.io:
var passInit = passport.initialize();
var passSess = passport.session();
io.use(function(socket, next){
passInit(socket.request, socket.request.res, next);
});
io.use(function(socket, next){
passSess(socket.request, socket.request.res, next);
});
Now in our io.on('connection') we can see socket.request.user
io.on('connection', function(socket){
console.log("socket connection");
console.log(socket.request.user)
console.log(socket.request.session.passport.user);
});
Upvotes: 4