meteor - 在 Meteor 中注销并快速重新登录后未加载用户对象

标签 meteor iron-router meteor-accounts

我遇到了奇怪的行为,并且无法正确调试它。我需要你的帮助。

如果我退出 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/

相关文章:

mysql - 如何从 meteor 访问 mysql 数据库

meteor - 简单模式 minDate maxDate

node.js - meteor 1.4 -( Node )sys 已弃用。改为使用 util

javascript - Meteor userId 存在但用户未定义

javascript - Meteor Galaxy 部署失败 - 容器崩溃

meteor 形态状态未保存

javascript - 如何使用 Meteor 获取更多数据并附加到文档

javascript - Meteor 嵌套 View 和产量

javascript - 带铁路由器和登录按钮的 meteor

meteor - Spotify 登录 Meteor 和 xinranxiao :accounts-spotify