无法在回调内设置Express会话

时间:2017-07-02 12:42:30

标签: node.js express cookies callback cookie-session

我知道有几个与此类似的问题,但它们都有重要的差异,这些差异并没有给我解决方案。 我正在使用client-session模块。我设置的内容与文档中指定的完全相同,但出于某种原因,我无法通过异步回调设置会话值。 这是我的代码

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;
    }
});

正如您所看到的,我尝试将会话从作为第三个参数传递的回调函数设置为我的login()函数。我不能说它根本不起作用,但它有效,比如一百万次。我没有在会话设置之前完成响应,但无论如何,当我检查会话时,这是我在绝大多数情况下得到的:

  

会话检查>>> {} true

即使这个输出

我也会一直显示设置会话。

但如果我将代码简化为:

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)}`);
    }
} 

这一切都像魅力一样。每次我想要设置/清除/检查会话,没有错误或错误。

我已经在这个问题上苦苦挣扎了3天了:(。我还尝试过不同的模块,比如客户端会话和其他几个。同样的结果。看起来问题更深了。

那么可以从异步回调中保存会话吗?我无法设置它,直到我从社交网络获取必要的数据

P.S。这是来自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;

现在更多细节:

如果在1秒内执行回调,则会设置会话。但是如果花费更多的时间,比如3秒多,那就不会。 我已经简化了我的login()函数:

function login(code, state, onComplete) {
    setTimeout(function() {
        onComplete({
            accessToken: "sfsd646481351gsFFHgDrgrrg",
            userId: "user",
            firstName: "John",
            lastName: "Doe"
        })}, 1000
    );
}

所以如果我设置1000毫秒到setTimeout()它工作正常,但如果我把它设置为3000,它就不会。看起来像在调用回调之前表达最终响应

另一个细节:

我刚刚发现,只有当我代理来自reactjs应用程序的请求时才会发生这种情况。如果我直接用邮递员调用API(快速)服务器,那么响应将等待多长时间就会无关紧要,cookie将被设置为没有问题

1 个答案:

答案 0 :(得分:0)

我找到了没有设置cookie的原因。这是因为我向社交网络提出了请求,并且在我设置我的

之前它返回了它的标题