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