19

当用户退出网站时,有什么办法可以接听吗?当他们这样做时,我需要做一些清理工作。使用内置的 meteor.js 用户帐户。

我将使用它进行一些验证,因此我需要一个不能代表客户端其他用户触发的解决方案 - 最好是完全服务器端的解决方案。

4

6 回答 6

9

您可以使用 Deps.autorun 设置自定义处理程序,观察 Meteor.userId() 反应变量的变化。

Meteor.userId()(和 Meteor.user())是反应变量,分别返回当前登录的 userId(如果没有,则为 null)和 Meteor.users 集合中的相应用户文档(记录)。

因此,人们可以通过对那些反应性数据源的修改做出反应来跟踪 Meteor 应用程序的登录/退出。

客户端/main.js:

var lastUser=null;

Meteor.startup(function(){
    Deps.autorun(function(){
        var userId=Meteor.userId();
        if(userId){
            console.log(userId+" connected");
            // do something with Meteor.user()
        }
        else if(lastUser){
            console.log(lastUser._id+" disconnected");
            // can't use Meteor.user() anymore
            // do something with lastUser (read-only !)
            Meteor.call("userDisconnected",lastUser._id);
        }
        lastUser=Meteor.user();
    });
});

在此代码示例中,我设置了一个源文件局部变量 (lastUser) 以跟踪上次登录应用程序的用户。然后在 Meteor.startup 中,我使用 Deps.autorun 设置响应式上下文(只要访问的响应式数据源之一被修改,就会重新执行代码)。这个反应上下文跟踪 Meteor.userId() 变化并做出相应的反应。

在断开代码中,您不能使用 Meteor.user() 但如果您想访问最后一个用户文档,您可以使用 lastUser 变量。如果要在注销后修改文档,可以使用 lastUser._id 作为参数调用服务器方法。

服务器/server.js

Meteor.methods({
    userDisconnected:function(userId){
        check(userId,String);
        var user=Meteor.users.findOne(userId);
        // do something with user (read-write)
    }
});

请注意,尽管恶意客户端可以使用任何用户 ID 调用此服务器方法,但除非您设置一些验证码,否则您不应该做任何关键的事情。

于 2013-07-29T12:55:53.397 回答
7

使用user-status我创建的包:https ://github.com/mizzao/meteor-user-status 。这完全是服务器端的。

有关用法,请参阅文档,但您可以将事件处理程序附加到会话注销:

UserStatus.events.on "connectionLogout", (fields) ->
  console.log(fields.userId + " with connection " + fields.connectionId + " logged out")

请注意,用户可以通过多个会话一次从不同位置登录。这个智能包检测所有这些以及用户是否在线。有关更多信息或实现您自己的方法,请查看代码。

目前该包不区分浏览器窗口关闭和注销,并将它们视为相同。

于 2013-07-29T14:57:26.290 回答
6

我们有一个类似的,但不是确切的要求。我们想在客户退出时对其进行一些清理。我们通过劫持做到了Meteor.logout

if (Meteor.isClient) {
  var _logout = Meteor.logout;
  Meteor.logout = function customLogout() {
    // Do your thing here
    _logout.apply(Meteor, arguments);
  }
}
于 2014-03-31T19:57:18.337 回答
2

@saimeunt 提供的答案看起来是正确的,但对于我需要的东西来说有点蓬松。相反,我采用了一种非常简单的方法,如下所示:

if (Meteor.isClient) {
    Deps.autorun(function () {
        if(!Meteor.userId())
        {
            Session.set('store', null);
        }
    });
}

但是,如果用户尚未登录,则会在页面加载期间触发,这可能是不可取的。所以你可以改用这样的东西:

if (Meteor.isClient) {
    var userWasLoggedIn = false;
    Deps.autorun(function (c) {
        if(!Meteor.userId())
        {
            if(userWasLoggedIn)
            {
                console.log('Clean up');
                Session.set('store', null);
            }
        }
        else
        {
            userWasLoggedIn = true;
        }
    });
}
于 2013-09-28T20:44:30.143 回答
1

没有一个解决方案对我有用,因为它们都遇到了无法区分用户手动注销与浏览器页面重新加载/关闭的问题。

我现在要进行黑客攻击,但至少它可以工作(只要您不提供除默认帐户-ui 按钮之外的任何其他注销方式):

Template._loginButtons.events({
    'click #login-buttons-logout': function(ev) {
        console.log("manual log out");
        // do stuff
    }
});
于 2014-01-07T05:41:40.657 回答
-2

您可以使用以下 Meteor.logout - http://docs.meteor.com/#meteor_logout

于 2013-07-29T12:50:06.407 回答