簡體   English   中英

無法使用'roles'包向meteor用戶添加角色

[英]unable to add roles to user with meteor using 'roles' package

我正在嘗試使用Atmosphere上提供的“角色”包但我無法使用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");
    }
  }
});

如果您查看Roles包中使用的代碼,您將看到他們使用您傳入的user / userId對用戶的集合執行查詢( 此處 ,從第〜623行開始):

try {
  if (Meteor.isClient) {
    // On client, iterate over each user to fulfill Meteor's
    // 'one update per ID' policy
    _.each(users, function (user) {
      Meteor.users.update({_id: user}, update)
    })
  } else {
    // On the server we can use MongoDB's $in operator for
    // better performance
    Meteor.users.update(
      {_id: {$in: users}},
      update,
      {multi: true})
  }
}

由於在將用戶對象插入集合之前調用onCreateUserdocs將返回的文檔直接插入到Meteor.users集合中 ),因此Roles在執行查詢時無法找到它。

為了解決這個問題,您必須等到用戶插入集合中。 如果你看一下Roles包,他們的所有例子都會顯示出來。 這里 ,(第二個例子,添加評論),以及許多其他:

// 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);
}

希望能夠解決你的問題。 所以基本上只需插入用戶然后添加權限。

要在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;
});

我不明白如何將Roles.addUsersToRoles與創建用戶時調用的onCreateUser函數集成。 正如您所發現的那樣,當您在OnCreateUser中調用它時,它不起作用。 但是在用戶創建循環中調用addUsersToRoles的示例情況似乎不適用於創建帳戶的新用戶的正常用例。

相反,我只是這樣做:

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

接受的答案強制您編寫由meteor通過accounts-ui / password給出的登錄邏輯的樣板代碼。 其他答案對底層實現做出假設,超時解決方案引入競爭條件。

為什么不這樣做:

 Accounts.onCreateUser(function(options, user) { ... Meteor.setTimeout(function () { Roles.addUsersToRoles(user._id, roles, group); },0); ... }); 

您可以在觸發onCreateUser調用的任何內容之后有效地添加角色並使用alanning的api添加到角色。 (測試流星1.0,角色1.2.13)

這里的問題實際上歸結為尋找post create用戶鈎子( onCreateUser不是)。

事實證明,存在這樣的事情! 它被稱為postSignUpHook

https://github.com/meteor-useraccounts/core/blob/master/Guide.md#options

我從這個答案中找到了這個:

https://stackoverflow.com/a/34114000/3221576

這是向使用樣板UserAccounts包創建的用戶添加角色的首選方法(即,如果您不使用Accounts.createUser滾動自己的角色)。

UPDATE

最終我最終使用matb33:collection-hooks根據這個評論:

https://github.com/alanning/meteor-roles/issues/35#issuecomment-198979601

只需將該代碼粘貼在Meteor.startup中即可按預期工作。

我不想重寫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);
  },
});

我的方式我發現這樣做,這很簡單。

我作為一個數組傳遞角色,所以我用[角色]

在客戶端,當用戶注冊時:

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');
  }
});

在我們的流星方法中(我使用lodash intersect方法來驗證我希望用戶選擇的角色)

  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');
      }
    }
  });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM