我在应用程序中使用Passport进行身份验证,并且还在使用Express。概括一下我的问题: 我的登录功能最初运行良好,但是在 任何
用户的会话超时后, 没有 用户可以登录。
我正在使用标准的本地策略进行身份验证。
我将根据自己的设置提供一个尽可能简单的示例:
//-------------
//Set up authentication with Passport
//-------------
var userModel = require('./models/user')(db);
passport.use(new LocalStrategy(
function(username, password, done) {
var errorMessage = 'Incorrect username/password combination.';
userModel.GetUserByUsername(username, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: errorMessage });
}
user.validatePassword(password, function(isPasswordCorrect) {
if (!isPasswordCorrect)
{
return done(null, false, { message: errorMessage });
}
//Update with login date
userModel.UpdateUserWithLogin(username, user.currentLoginTime, function(err){
//if we have an error here, we should probably just log it
if(err)
{
console.log(err);
}
});
return done(null, user);
});
});
}
));
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
userModel.GetUserByUsername(user._id, function(err, user) {
done(err, user);
});
});
//-------------
//Set up express and configure
//-------------
var sessionStore = new SkinStore(db);
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.engine('html', consolidate.swig);
app.set('view engine', 'html');
swig.init({
root: '.',
allowErrors: true, // allows errors to be thrown and caught by express instead of suppressed
autoescape: false});
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser("[mysecrethere]"));
app.use(express.session({ store: sessionStore,
cookie: { expires : new Date(Date.now() + 3600000) } //1 Hour
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(expressValidator);
app.use(express.static(path.join(__dirname, 'public')));
//Dynamic helpers
app.use(require('./helpers/DynamicHelpers'));
app.use(app.router);
});
app.get('/login', routes.login);
app.post('/login', passport.authenticate('local', {failureRedirect: '/login',
badRequestMessage: "Please enter username and password",
failureFlash: true }),
function(req, res) {
var targetUrl = req.session.pageAfterLogin;
delete req.session.pageAfterLogin;
res.redirect(targetUrl || '/account');
});
app.get('/account', IsAuthenticated, routes.account.show);
和IsAuthenticated辅助函数:
function IsAuthenticated(req,res,next){
if(req.isAuthenticated())
{
next();
}
else
{
//save the requested page and then redirected
req.session.pageAfterLogin = req.url;
req.flash("error", "You must be logged in first!");
res.redirect('/login');
}
}
通过调试可以找到的是,在成功进行身份验证之后(cookie过期之后),我击中了这个逻辑(从上面):
function(req, res) {
var targetUrl = req.session.pageAfterLogin;
delete req.session.pageAfterLogin;
res.redirect(targetUrl || '/account');
}
我可以在其中看到“ req”已正确设置了会话,并正确存储了Passport信息。然后,发生重定向, 新
请求没有存储会话信息,并且具有全新的会话ID。我怀疑没有在客户端上设置cookie,事实确实如此,这应该可以解释缺少一致的会话的原因。
但是,我无法弄清楚 为什么 没有设置新的cookie。应用程序的配置方式是否有问题,以表明发生这种情况的原因?
我应该补充一点,重新启动Node.js实例可以解决此问题,但这并不是生产中可以容忍的。
谢谢。
更新 :我运行了Fiddler,以查看HTTP /
S流量发生了什么,我可以看到,最初运行时,我在浏览器中设置了一个cookie(我尝试了几次),然后将该cookie传递回服务器。后续请求。
当它 不起作用时 ,浏览器不会将cookie传递到服务器,因此Node会发送Set-
Cookie标头,该标头每次提供一个新的cookie。到目前为止,我还没有运气确定原因。
我弄清楚了,尽管我不喜欢这个答案。
tl; dr; -使用maxAge而不是过期。
问题的根源是在每个Cookie上设置的到期日期(由Express自动设置)。我注意到,每个设置的Cookie都具有相同的到期日期,最终该到期日期是过去的日期,因此立即到期。
原因在这里:
cookie: { expires : new Date(Date.now() + 3600000) }
服务器启动后,仅创建一次新的日期。这导致到期时间每次都相同。根据原始帖子中的代码,我无法弄清楚为什么它不起作用,但是我在网上找到的每个示例都使用完全相同的代码。我通过定义一个创建此Date的函数并检查它是否仅在服务器启动时被调用来验证这一点。
为了解决此问题,我定义了maxAge而不是“ expires”。maxAge需要花费毫秒数而不是日期,并且似乎正确设置了所有cookie的到期日期。
我很想听听是否有人可以一开始就解释为什么会这样,因为其他人似乎已经成功地使用了它。 有什么想法吗?
请参阅下面的工作代码
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.engine('html', consolidate.swig);
app.set('view engine', 'html');
swig.init({
root: '.',
allowErrors: true, // allows errors to be thrown and caught by express instead of suppressed
autoescape: false});
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser("[mysecrethere]"));
app.use(express.session({ store: sessionStore,
cookie: { maxAge : 3600000 } //1 Hour
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(expressValidator);
app.use(express.static(path.join(__dirname, 'public')));
//Dynamic helpers
app.use(require('./helpers/DynamicHelpers'));
app.use(app.router);
});
该函数的目标是创建一个周期性地发出值的流,直到遇到与谓词匹配的值。 下面是我提出的一些框架代码: 和一些将检索正确阶段的callable,我应该能够传递callable和谓词检查是否,并轮询直到获得事件。 我遇到的问题是,当收到的事件不是最终事件时,生成一个可观察的事件。在这种情况下,observable应该继续轮询事件,直到它接收到与谓词匹配的事件,或者直到它没有更多的订阅服务器。 这一点可以观
但问题是我无法将数据从Firebase转换为Local。save方法将转换为Timestamp fine。 任何解决办法。
我试图实现java.time来解析不同的日期格式并返回为java.sql.日期。但是,如果我使用java.sql.Date.value(LocalDate date),我将失去时间。如何获得与java.sql.日期(java.util.日期date.get时间())相同的方式?我的应用程序中可能的格式是。 ormatter.of模式("yyyy-MM-dd");日期时间格式(DateTimeFor
●仅可支持提前、等于当天的预警。 ●所要进行到期预警的图层必须含有日期类型字段。 ●预警范围:想要进行预警的图层。 ●预警方式: 高亮闪烁、语音提醒、弹窗提醒。 注意事项: ●一个地图可以设置最多30个预警项 ●预警范围覆盖点线面的属性内容,暂不包含动态预警 ●消息提醒为临时一次性提醒,重新刷新页面消息重新出现 [查看原图]
问题内容: 在PHP中,将RGB三元组转换为HSV值的最直接方法是什么? 问题答案:
我对SAML断言到期和应用程序会话到期感到困惑。 简单地说,当我们在容器中部署了一个应用程序时,就会创建一个会话。这个会话到期可以通过下面的条目来控制web.xml 接下来,当我使用SAML扩展的Spring Security性时,显然同样的会话概念也适用。(如果有必要的话,我正在WildFly 8.2中部署应用程序) 此外,当应用程序会话过期时,注销行为似乎等同于本地注销概念。 到目前为止一切都
我正在使用这段代码生成objects,但有时我会遇到这个错误(错误参数#-1到'addBody'(需要代理,得到零))知道为什么吗?
问题内容: 我想将日期时间序列转换为季节,例如第3、4、5个月,我想用2(春季)替换它们;对于6、7、8个月,我想用3(夏季)等替换它们。 所以,我有这个系列 这是我一直在尝试使用的代码,但无济于事。 和 两种解决方案均无效,特别是在第一个实现中,我收到一个错误: ValueError:具有多个元素的数组的真值不明确。使用a.any()或a.all() 而第二个是有错误的大列表。有什么想法吗?谢谢