Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无法使用';角色';包裹_Javascript_Meteor_Roles_Atmosphere - Fatal编程技术网

Javascript 无法使用';角色';包裹

Javascript 无法使用';角色';包裹,javascript,meteor,roles,atmosphere,Javascript,Meteor,Roles,Atmosphere,我试图使用Atmosphere上提供的“roles”包,但无法将其用于Accounts.onCreateUser(),我可以在github上获得示例。当我注册一个用户时,我想给他们添加一个角色,当我测试是否分配了这个角色时,它不会选择它 这是我的密码 /server/users.js Accounts.onCreateUser(function(options, user){ var role = ['admin']; Roles.addUsersToRoles(user, role);

我试图使用Atmosphere上提供的“roles”包,但无法将其用于Accounts.onCreateUser(),我可以在github上获得示例。当我注册一个用户时,我想给他们添加一个角色,当我测试是否分配了这个角色时,它不会选择它

这是我的密码

/server/users.js

Accounts.onCreateUser(function(options, user){
  var role = ['admin'];
  Roles.addUsersToRoles(user, role);
  return user;
});
/client/page.js

Template.hello.events({
  'click input': function () {
    var loggedInUser = Meteor.user();
    if (Roles.userIsInRole(loggedInUser, ['admin'])) {
      console.log("Hi Admin!");
    }else{
      console.log("Please Log In");
    }
  }
});

如果查看
角色
包中使用的代码,您将看到他们使用传入的用户/userId对用户集合执行查询(,从第623行开始):

由于在将用户对象插入集合之前调用了
onCreateUser
(:返回的文档直接插入Meteor.users集合),
角色执行查询时无法找到它

要解决此问题,必须等待用户插入集合。如果您查看
角色
包,它们的所有示例都显示了这一点。例如,(第二个例子,添加了注释),以及许多其他内容:

// insert user and retrieve the id
id = Accounts.createUser({
  email: user.email,
  password: "apple1",
  profile: { name: user.name }
});

// now we can verify that the user was inserted and add permissions
if (user.roles.length > 0) {
  Roles.addUsersToRoles(id, user.roles);
}

希望这能对你的问题有所启发。因此,基本上只需插入用户,然后在之后添加权限。

我不知道如何将Roles.addUsersToRoles与创建用户时调用的onCreateUser函数集成。在OnCreateUser中调用它时,它不起作用,正如您所做的,正如您所发现的。但是在用户创建循环中调用addUsersToRoles的示例案例似乎不适用于新用户创建帐户的正常用例

相反,我只是:

Accounts.onCreateUser(function(options, user){
  var role = ['admin'];
  user.roles = role
  return user;
});

要在用户文档被
accounts
包插入后向其添加内容,请尝试此模式。注意,您必须
meteor add random
才能生成
userId
,这在本上下文中是安全的

Accounts.onCreateUser(function (options, user) {
    // Semantics for adding things to users after the user document has been inserted
    var userId = user._id = Random.id();
    var handle = Meteor.users.find({_id: userId}, {fields: {_id: 1}}).observe({
        added: function () {
            Roles.addUsersToRoles(userId, ['admin']);
            handle.stop();
            handle = null;
        }
    });

    // In case the document is never inserted
    Meteor.setTimeout(function() {
        if (handle) {
            handle.stop();
        }
    }, 30000);

    return user;
});

接受的答案迫使您为meteor通过帐户ui/密码给出的登录逻辑编写样板代码。 其他答案对底层实现进行了假设,超时解决方案引入了竞争条件

为什么不这样做:
Accounts.onCreateUser(函数(选项,用户){
...
Meteor.setTimeout(函数(){
Roles.addUsersToRoles(用户id、角色、组);
},0);
...

});我不想重写Meteor帐户包给出的逻辑,自己设置ID,或者使用setTimeout

相反,我让跟踪程序代码监视
Meteor.user()
调用,如果登录,则返回用户,否则返回null

因此,有效地,一旦用户登录,此代码将检查他们是否已被分配角色,以及是否尚未添加角色

我确实需要使用Meteor方法,因为我不希望角色与客户端发生冲突,但您可以改变这一点

/* client */
Tracker.autorun(function () {
  var user = Meteor.user();
  if (user && !Roles.getRolesForUser(user).length) {
    Meteor.call('addUserRole', user);
  }
});

/* server */
Meteor.methods({
  addUserRole: function (user) {
    Roles.addUsersToRoles(user, user.profile.edmodo.type);
  },
});

我发现这样做的方法很简单

我将角色作为数组传递,因此使用了[role]

在客户端,当用户注册时:

var role = $(event.target).find('#role').val();

/*
 * Add account - Client-Side
 */
Accounts.createUser(account, (error) => {
  if (error) {
    console.log(error);
  } else {
    // server-side call to add the user to the role
    // notice Meteor.userId() and [role]
    Meteor.call('assignUserToRole', Meteor.userId(), [role]);

    // everything went well, redirect to home
    FlowRouter.go('home');
  }
});
在我们的meteor方法中(我使用lodash intersect方法来验证我希望用户选择的角色)


这里的问题实际上归结为寻找一个postcreate用户钩子(而
onCreateUser
不是)

原来,这样的事情是存在的!它被称为
postSignUpHook

我从这个答案中发现:

这是向使用样板UserAccounts包创建的用户添加角色的首选方法(即,如果您没有使用
Accounts.createUser

更新

最终,我使用了matb33:collection钩子,如下所示:


只要在Meteor.startup中插入该代码,事情就会按预期进行。

回答得很好。我以前见过这个问题,我愿意接受建议。也许只是在文档中特别指出这一点?@alanning谢谢!是的,那可能会引起一些混乱。我个人建议在文档中添加一些内容。即使只是在atmosphere页面的client部分之后添加注释,也可能会发现其中一些情况。否则,希望人们会开始找到与之相关的SO帖子。那么使用accounts ui创建的用户呢?@Dan,@DoctorPangloss的回答让我们使用方便的
onCreateUser
。我们使用自己的自定义Meteor方法创建用户,因此在我们的应用程序中,我们按照@Firo建议的方式进行创建。我添加了一个新函数的示例,该函数直接在用户对象上设置角色,但只要角色使用的db结构保持不变(正如DP在他的一条评论中提到的)。下一版本的角色可能会使用一个标志,该标志允许您指示用户角色应直接在用户对象上更新,以便可以在onCreateUser中直接使用。没有关于什么时候会这样的计划。虽然这对角色有效,但如果你同时拥有角色和组,它就不起作用了。通常你会得到这样的结果:
“角色”:{“\uuuu全局角色”\uuuuuuu:[“管理员”]},
如果
“管理员”
还不在
角色
集合中,这会起作用吗?这是否会将其添加到
roles
集合中?与
user.roles=['admin']
相比,它的优势是什么,即dojomouse的答案?@dojomouse的答案假设了
allaning:roles
的工作原理。如果他们不将角色存储在字符串数组中呢?如果另一段代码修改了角色怎么办?如果您更新了
角色
,而他又添加了一种方法,该怎么办?在对dojomouse解决方案的评论中,您实际上将看到一个示例,说明如果直接修改此数组,您将100%破坏某些内容。通过这种方式,您可以保证只要
addUsersToRoles
不改变,您就不会做其他事情。这比Joe上面的答案复杂得多,Joe的答案不需要手动设置用户id,也不需要添加其他不必要的依赖项
var role = $(event.target).find('#role').val();

/*
 * Add account - Client-Side
 */
Accounts.createUser(account, (error) => {
  if (error) {
    console.log(error);
  } else {
    // server-side call to add the user to the role
    // notice Meteor.userId() and [role]
    Meteor.call('assignUserToRole', Meteor.userId(), [role]);

    // everything went well, redirect to home
    FlowRouter.go('home');
  }
});
  Meteor.methods({
    // when a account is created make sure we limit the roles
    assignUserToRole: (userId, roles) => {
      check(userId, String);
      check(roles, Array);

      var allowedRoles = ['student', 'parent', 'teacher'];
      if (_.intersection(allowedRoles, roles).length > 0) {
        Roles.addUsersToRoles(userId, roles, 'user');
      } else {
        Roles.addUsersToRoles(userId, ['student'], 'user');
      }
    }
  });