I know there's a few questions similar to this already, but they all have crucial differences which do not give me the solution. I'm using client-session module. I've set everything up exactly like it's specified in the docs, but for some reason I can't set session values from async callback. Here is my code
router.get('/auth', function(req, res, next) {
var params = req.query;
var act = params.act;
switch (act) {
case Constants.ACT_LOGIN_CHECK:
console.log('SESSION CHECK >>> ', JSON.stringify(req.session), req.session.isNew);
res.send(`SESSION CHECK >>> ${JSON.stringify(req.session)} ${req.session.isNew}`);
break;
case Constants.ACT_LOGIN_REQUEST:
var code = params.code;
var state = params.state;
login(code, state, function(result) {
if (result) {
if (result.accessToken) {
// console.log("WRITING SESSION BEFORE: ", JSON.stringify(req.session), req.session.isNew);
req.session.accessToken = result.accessToken;
req.session.userId = result.userId;
req.session.firstName = result.firstName;
req.session.lastName = result.lastName;
// req.session.photoURL = result.photoURL;
req.session.save();
console.log(`SESSION SET >>> ${JSON.stringify(req.session)} ${req.session.isNew}`);
res.send(`SESSION SET >>> ${JSON.stringify(req.session)} ${req.session.isNew}`);
}
} else {
res.end();
}
});
break;
case Constants.ACT_LOGOUT_REQUEST:
req.session = null;
res.send(`LOGGED OUT, SESSION >>> ${JSON.stringify(req.session)}`);
console.log('LOGGED OUT, SESSION >>> ', JSON.stringify(req.session));
break;
}
});
As you can see, I'm trying to set the session from callback function passed as third argument to my login() function. I can't say it doesn't work at all but it works, like, one time in a million. I'm not finilazing the response before the session is set, but anyway, when I check the session, this is what i get in the vast majority of cases:
SESSION CHECK >>> {} true
Even though this output
Is also shown all the time I set the session.
But if I simplify the code to this:
router.get('/auth', function(req, res, next) {
var params = req.query;
var act = params.act;
if (act == Constants.ACT_LOGIN_CHECK) {
console.log('SESSION CHECK >>> ', JSON.stringify(req.session), req.session.isNew);
res.send(`SESSION CHECK >>> ${JSON.stringify(req.session)} ${req.session.isNew}`);
} else if (act == Constants.ACT_LOGIN_REQUEST) {
req.session.accessToken = "595a751fa174ecbda109b14339b827941b58f7d0b10b495d0f85819e749e0b42c320dcda71520342cd020";
req.session.userId = 2195783;
req.session.firstName = "John";
req.session.lastName = "Doe";
req.session.save();
console.log('SETTING SESSION >>> ', JSON.stringify(req.session), req.session.isNew);
res.send(`SESSION SET >>> ${JSON.stringify(req.session)} ${req.session.isNew}`);
} else {
req.session = null;
console.log(`SESSION KILLED >>> ${JSON.stringify(req.session)}`);
res.send(`SESSION KILLED >>> ${JSON.stringify(req.session)}`);
}
}
It all works like a charm. The session is set / cleared / checked every time I want, with no errors or bugs.
I've been struggling with this issue for 3 days now :(. I've also tried different modules like client-sessions and several others. The same result. Seems like the problem is deeper.
So is it possible at all to save session from async callback? I can't set it until I get the necessary data from social network
p.s. Here is the actual initialization code from app.js
var Constants = require('./constants');
var express = require('express');
var path = require('path');
var app = express();
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieSession = require('./cookiesession');
var bodyParser = require('body-parser');
const user = require('./routes/user');
const auth = require('./routes/auth');
const posting = require('./routes/posting');
const messages = require('./messages');
const mongo = require('./mongo');
app.use(express.static(path.join(__dirname, 'public')));
app.set('trust proxy', true);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieSession({
secret: Constants.COOKIE_SESSION_KEY_1
}));
app.use(function (req, res, next) {
req.sessionOptions.maxAge = Constants.COOKIE_SESSION_MAX_AGE;
next();
})
app.use('/api/', user);
app.use('/api/', posting);
app.use('/api/', auth);
module.exports = app;
MORE DETAILS NOW:
If the callback is executed in 1 second, the session will be set. But if it takes up more time, like 3+ seconds, it won't. I've simplified my login() function like this:
function login(code, state, onComplete) {
setTimeout(function() {
onComplete({
accessToken: "sfsd646481351gsFFHgDrgrrg",
userId: "user",
firstName: "John",
lastName: "Doe"
})}, 1000
);
}
So in case I set 1000 ms to setTimeout() it works fine, but if I set it to 3000, it won't. Looks like express finalizes response before the callback is called
ANOTHER DETAIL:
I've just found out, that this only happens if I proxy the request from reactjs app. If I call API (express) server directly with postman, it won't matter how much time the response will wait, the cookie will be set with no problems