Open Jpunt opened 9 years ago
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.
Similar to #148, I'm can't seem to set a manual
sessionID
. Setting it insignedCookies
like seems to be the solution doesn't seem to work: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: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 differentsessionID
.Any help on this would be great!