在我的Meteor.js应用程序中,我想让管理员强行注销用户。
用例是我的应用程序正在为最终用户提供服务,并且每当超级用户登录时该服务都是打开的。如果超级用户忘记明确注销,该服务似乎是开放的最终用户。如果管理员看到这一点,他/她应该能够强行注销登录用户,并为最终用户关闭服务。
Meteor.js可以吗?如果是这样,怎么样?这个用例有更好的/其他方法吗?
编辑:添加了一些我尝试过的远程注销示例,以便为@Akshat澄清。
示例1(不能按我的意愿工作):
在注销方法中:
if (user.profile.role === ROLES.ADMIN) {
Meteor
.users
.update({
_id: options.userId
},
{
$set: {
'services.resume.loginTokens' : []
}});
} else {
throw new Meteor.Error(403, "You are not allowed to access this.");
}
在我的application.js中:
var lastUserId;
Deps.autorun(function () {
if(Meteor.user()) {
if (Meteor.user().profile && Meteor.user().profile.firstName) {
console.log("USER LOGGED IN");
console.log("LENGTH LOGINTOKENS",
Meteor
.user()
.services
.resume
.loginTokens.length); // This is always 1
lastUserId = Meteor.user()._id;
if (Meteor.user().services.resume.loginTokens.length === 0) {
// This never fires, and thus the client does not know until
// manually refreshed. Of course I could keep a forceLogOut-variable
// as done in the next example.
window.location.reload();
}
}
} else {
console.log("SOMETHING CHANGED IN METEOR.USER");
if (lastUserId) {
console.log("THE USER IS LOGGED OUT");
Meteor.call('userLoggedOut',
{
userId: lastUserId
});
lastUserId = null;
}
}
});
示例2(当我在客户端使用forceLogOut和Meteor.logout()时,这可以正常工作。):
在注销方法中:
if (user.profile.role === ROLES.ADMIN) {
Meteor
.users
.update({
_id: options.userId
},
{
$set: {
'services.resume.loginTokens' : [],
'profile.forceLogOut': true
}});
} else {
throw new Meteor.Error(403, "You are not allowed to access this.");
}
在我的application.js中:
var lastUserId;
Deps.autorun(function () {
if(Meteor.user()) {
if (Meteor.user().profile && Meteor.user().profile.firstName) {
console.log("USER LOGGED IN");
console.log("LENGTH LOGINTOKENS",
Meteor
.user()
.services
.resume
.loginTokens.length); // This is always 1
lastUserId = Meteor.user()._id;
if (Meteor.user().profile.forceLogOut) {
// Small example 1:
// When logintokens have been set to [], and forceLogOut
// is true, we need to reload the window to show the user
// he is logged out.
window.location.reload();
// END Small example 1.
// Small example 2:
// When already keeping this variable, I might as well just use
// this variable for logging the user out, and no resetting of
// loginTokens are needed, or reloading the browser window.
// This seems to me as the best way.
console.log("FORCING LOGOUT");
Meteor.logout();
// END Small example 2.
// And finally resetting the variable
Meteor.call('resetForceLogOut',
{
userId: Meteor.user()._id
});
}
}
} else {
console.log("SOMETHING CHANGED IN METEOR.USER");
if (lastUserId) {
console.log("THE USER IS LOGGED OUT");
Meteor.call('userLoggedOut',
{
userId: lastUserId
});
lastUserId = null;
}
}
});
答案 0 :(得分:26)
您必须从数据库中删除所有loginTokens
。它将通过此查询为所有用户执行此操作。如果要注销较小的用户子集或排除当前用户,则可以自定义选择器。
Meteor.users.update({}, {$set : { "services.resume.loginTokens" : [] }}, {multi:true});
有几件事:
答案 1 :(得分:2)
退出所有人,但不是当前用户(您):
Meteor.users.update({
_id: {
$ne: Meteor.user()._id
}
}, {
$set: {
"services.resume.loginTokens": []
}
}, {
multi: true
});
答案 2 :(得分:0)
我最近遇到了类似的问题 - 在删除当前登录用户的恢复令牌后,Tracker.autorun无法(并且应该在这种情况下)检测Meteor.userId()中的更改,如下所示代码:
Tracker.autorun(() => {
console.log('currrent user', Meteor.userId());
});
原来,问题是由登录用户订阅的其中一个出版物引起的。在与路由相关的代码中的某处(我使用的是Iron路由器),我有:
export const AppController = RouteController.extend({
waitOn() {
if (!Meteor.userId()) {
return Router.go('signIn');
}
Meteor.subscribe('data'),
},
});
出版物代码是:
Meteor.publish('data', function () {
if (!this.userId) {
return; // this line caused the logout bug
}
return MyCollection.find();
}
错误是由未设置this.userId
时返回undefined(而不是空数组)引起的,这导致发布永远不会准备好。由于某些奇怪的原因,这也导致Tracker在删除恢复令牌时不会触发。
所以解决方法是:
Meteor.publish('data', function () {
if (!this.userId) {
return []; // this is the correct way to return empty set
}
return MyCollection.find();
}