我遇到了奇怪的行为,并且无法正确调试它。我需要你的帮助。
如果我退出 Meteor,一切看起来都很好。
如果我等待大约 2 秒并再次登录,一切仍然很好。但是,如果我注销并快速再次登录,则在登录过程之后,Meteor.user()
对象将设置为 null,这会导致我的路由器将用户重定向回登录页面。
知道为什么会发生这种情况吗?我该如何防止这种情况发生?
我花了 2 小时尝试了几件事,但没有成功。任何建议都是非常受欢迎的。
编辑
这是我的全局 onBeforeAction
函数:
Router.onBeforeAction(function() {
// Ensures the user is logged in
if (!Meteor.userId()) {
please_login();
}
// Email address not verified for 24h? Please verify it!
else {
var self = this;
// Waits for the user object to be passed over DDP
function wait_for_user_data() {
if (Meteor.user() && Meteor.user().emails && Meteor.user().profile) {
var user = Meteor.user();
var now = new Date().getTime();
var ca = user.createdAt.getTime();// Created At
var cs = (now - ca) / (24 * 60 * 60 * 1000);// Created Since (in days)
var urls = ["email_verification_required", "email_verification"];
if (cs > 1 &&
!user.emails[0].verified &&
urls.indexOf(self.url.split("/")[1]) == -1) {
Router.go("email_verification_required");
}
else {
self.next();
}
}
else {
setTimeout(wait_for_user_data, 500);
}
}
wait_for_user_data();
}
},
{except: ['home', 'login', 'register', 'password_recovery', "email_verification", "profile"]})
实际发生的情况如下:
当我注销后立即登录时,会调用 self.next()
,但当前用户属性 (Meteor.user().emails
和 >Meteor.user().profile
) 由于某种原因尚未加载。它们是未定义的
。正如您所看到的,我尝试通过等待定义它们来解决此问题,但随后我收到以下错误消息:
Route dispatch never rendered. Did you forget to call this.next()
in an onBeforeAction?
这似乎导致 Meteor 将 Meteor.user()
设置为 null
,因此我的用户被重定向到登录页面...
编辑BIS
这就是我处理用户数据的发布/订阅的方式。我有 2 种不同的发布/订阅集,一种适用于所有用户,另一种仅适用于登录用户。
Meteor.publish('users', function() {
var args = {};
var fields = {
'_id': 1,
'createdAt': 1,
'profile.firstname' : 1,
'profile.lastname' : 1,
'profile.lang' : 1,
};
// Only admins can access those sensible information
if (this.userId && Roles.userIsInRole(this.userId, 'admin')) {
fields["emails"] = 1;
fields["profile.celular"] = 1;
args : {$ne : {_id: this.userId}};
}
return Meteor.users.find(args, {fields: fields});
});
Meteor.publish('user', function() {
return Meteor.users.find({_id: this.userId});
});
这就是我在路由器配置中订阅这两个出版物的方式:
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
waitOn: function() {
return [Meteor.subscribe('user'), Meteor.subscribe('users')];
},
});
最佳答案
如果没有代码示例(并且知道您正在使用哪个路由器),我将猜测您的路由器代码如下所示:
if (!Meteor.user()) {
//... redirect or change tempalte etc
}
您可以检查另一个值,
if (!Meteor.user() && !Meteor.loggingIn()) {
//... redirect or change tempalte etc
}
您可以使用这些的各种组合来处理登录状态,例如在加载 View 中进行日志记录等
了解更多信息
正在回调中调用重定向,当前用于使用密码登录功能,查看 docs它应该在链接的 onLogin 回调上调用,因为这可以确保登录成功,尽管在此处进行重定向,可能无法提供与在 react 性上下文中执行此操作相同的控制范围,例如 Controller 上的 before 钩子(Hook)或自动运行在登录模板 onCreated 回调中创建的函数。
关于meteor - 在 Meteor 中注销并快速重新登录后未加载用户对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34254235/