0

我知道已经有一些与此类似的问题,但是它们都有重要的区别,这并没有给我解决方案。我正在使用客户端会话模块。我已经完全按照文档中指定的方式设置了所有内容,但是由于某种原因,我无法从异步回调中设置会话值。这是我的代码

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() 函数的回调函数设置会话。我不能说它根本不起作用,但它起作用,就像百万分之一。我没有在设置会话之前完成响应,但无论如何,当我检查会话时,这是我在绝大多数情况下得到的:

会话检查 >>> {} 真

即使这个输出

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

但是,如果我将代码简化为:

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 天 :(。我还尝试了不同的模块,如客户端会话和其他几个模块。结果相同。似乎问题更深了。

那么是否有可能从异步回调中保存会话?在我从社交网络获得必要的数据之前,我无法设置它

ps 这是来自 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
    );
}

因此,如果我将 setTimeout() 设置为 1000 毫秒,它可以正常工作,但如果我将其设置为 3000,则不会。看起来 express 在调用回调之前完成响应


另一个细节:

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

4

1 回答 1

0

我找到了未设置 cookie 的原因。这是因为我向社交网络发出请求,它在我设置我的标题之前返回了它的标题

于 2017-07-03T02:36:55.420 回答