session
session copied to clipboard
Can't set manual sessionID
Similar to #148, I'm can't seem to set a manual sessionID. Setting it in signedCookies like seems to be the solution doesn't seem to work:
app
.use(function(req, res, next) {
if(req.query.sessionID) {
req.signedCookies["connect.sid"] = req.query.sessionID;
}
next();
})
.use(session({
httpOnly: false,
secret: 'secret',
resave: false,
saveUninitialized: true
})
.get('/session', function(req, res) {
console.log('sessionID:', req.sessionID);
req.session.tmp = req.session.tmp + 1 || 0;
req.session.save();
res.send('session: ' + req.session.tmp);
})
When I hit http://localhost:3000/session?sessionID=42 a couple of times, the counter goes up. When I hit that exact same url in a different browser I expect it to pick up the count from the session, but it does not.
An observation: The log for req.sessionID is not what I gave to the query string, so I guess it's initialising its own sessionID instead.
I've also tried a custom genid like so:
.use(session({
httpOnly: false,
secret: 'secret42',
resave: false,
saveUninitialized: true,
genid: function(req) {
return req.query.sessionID || uuid.v1();
}
})
This seemed like a cleaner solution anyway, but it also doesn't work for me. It sets the sessionID correctly for the first hit, but it won't update it for requests with a different sessionID.
Any help on this would be great!
Yes, that work around only works for non-browsers, which do not carry cookies. For this to work in web browsers, you'll need to do a lot of work, sadly, to sign that unsigned value, then form a fake cookie header from it, place it in the right req.headers spot, and remove the incoming value. Otherwise, this module needs to be modified to allow an alternative method besides cookies.
The old express 3 didn't allow for an alternative, either, but it was easier to trick that module (or older versions of this module, which was a copy and paste of express 3).
Another workaround could be using the solution from that other issue and also just delete all incoming cookies (if that is an option) by adding "delete req.headers.cookie".
Thats too bad.. Deleting req.headers.cookie results in no working sessions at all. Can you point me in the right direction on how to implement the other solution?
Deleting req.headers.cookie results in no working sessions at all
Really? It should work, when combined with the workaround of setting req.signedCookies you have above (i.e. do the delete when you set req.signedCookies).
As for the fuller solution, I can see about trying to write it up when I get back to a computer, but really, a PR to allow non-cookie-based sessions would be better in the long run.
Essentially we don't officially support non-cookie-based sessions until there is a PR offered up that works well and is accepted.
To avoid any mixups, this is what i've tried:
app
.use(function(req, res, next) {
if(req.query.sessionID) {
req.signedCookies["connect.sid"] = req.query.sessionID;
delete req.headers.cookie;
}
next();
})
.use(session({
httpOnly: false,
secret: 'secret',
resave: false,
saveUninitialized: true
})
.get('/session', function(req, res) {
console.log('sessionID:', req.sessionID);
req.session.tmp = req.session.tmp + 1 || 0;
req.session.save();
res.send('session: ' + req.session.tmp);
})
I agree that a non-cookie-option in the module would be a better solution. I'll investigate what needs to be done in the next couple days.
This option turned out to be pretty easy to implement, but I don't have a huge amount of experience in express-middlewares. Can you take a look and see if it makes any sense?
https://github.com/expressjs/session/compare/cda52fcdac4c84f6c54d161e0380fe5fbb9b93ae...Jpunt:master
If so, I'll make some tests and a PR :)
Just go ahead and make the PR right away :) I can comment on it and we can always iterate!
Alright! :metal:
This was a real life saver. Can this be merged onto master ?
Agreed. When can we expect this to be merged into master?
really need to set the manual sessionID
emergency emergence emerge merger merger ... merge
Middleware configuration:
const uid = require("uid-safe").sync;
var middleware = session({
genid: function(req) {
if ( (req.session) && (req.session.uid) ) {
return req.session.uid + "_" + uid(24);
} else {
return uid(24);
}
}
secret: config.cookieSecret,
store: sessionStore,
resave: false,
saveUninitialized: false
})
On successfull authentification:
req.session.uid = data.id;
req.session.regenerate(function (err) {
if (err) throw err;
req.session.uid = data.id;
// ...
});
@em92 - Clever... Thanks!
Simply remove cookie/headers by creating a middleware for route, and run before session middleware -> this help express-session alway run to genid function
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
let app = express();
app.use('/test', (req, res, next) => {
console.log("Delete cookie, header values:", req.headers);
delete req.cookies;
delete req.headers['cookie'];
next();
})
app.use(session({
genid: function(req) {
console.log('Run to genid function', req.query);
if (req.query.ssId) {
return req.query.ssId;
} else {
return makeid(12);
}
},
resave: false,
saveUninitialized: false
}));
const router = express.Router()
router.use('/test', (req, res, next) => {
req.session.user_data={name: "cuong ta"};
res.json({
receive: true,
sessionId: req.sessionID
});
})
Test with http://localhost/test?ssId=123456
Need this too: I.e. allow to customise the way a request is associated with its session, as opposed to hard coded dependency on sid-cookie.
@em92 genid does not appear to be a solution. In will not re-associate the req with an existing session. The SID changes but the existing session data is lost in my testing.