【问题标题】:Picking up meteor.js user logout拿起meteor.js用户注销
【发布时间】:2013-07-29 04:46:27
【问题描述】:

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

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

【问题讨论】:

标签: javascript meteor


【解决方案1】:

您可以使用 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)
    }
});

请注意,尽管恶意客户端可以使用任何 userId 调用此服务器方法,因此除非设置一些验证码,否则您不应执行任何关键操作。

【讨论】:

  • 嘿 - 在这种情况下,我确实需要避免恶意客户端能够调用它,因为它会导致玩家退出游戏,而我显然不允许人们这样做彼此。关于如何设置验证码并将其绑定到特定用户的任何想法?
【解决方案2】:

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

查看文档以了解用法,但您可以将事件处理程序附加到会话注销:

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

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

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

【讨论】:

  • 谢谢 - 我一定会看看的!
  • 这是一个很酷的包。知道如何仅在用户登录/注销时实现事件触发器,不包括浏览器/窗口关闭?任何提示/方向都会很棒。谢谢@andrew-mao
  • 当用户退出时如何将用户重定向到某个特定路径?
  • @mfq 你可以使用Meteor.user() 的响应性,当客户端注销时它会变成undefined。请参阅 saimeunt 对此问题的回答。
【解决方案3】:

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

if (Meteor.isClient) {
  var _logout = Meteor.logout;
  Meteor.logout = function customLogout() {
    // Do your thing here
    _logout.apply(Meteor, arguments);
  }
}

【讨论】:

  • 这句话很简单,而且效果很好。我只是想将“已注销”的用户重定向到主页,这是一种简单 + 干净的方法。
【解决方案4】:

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

【讨论】:

  • 将 deps.autorun 注册放在 onLogin 处理程序中似乎会很好,这样您只有在知道用户已登录时才注册它。不过好东西!
【解决方案5】:

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

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

Template._loginButtons.events({
    'click #login-buttons-logout': function(ev) {
        console.log("manual log out");
        // do stuff
    }
});

【讨论】:

  • 真的很有趣。您是否需要 aldeed:template-extension 或类似的包来扩展/覆盖 accounts 包中模板的功能?
  • 谢谢,这也完美地满足了我的需要!
【解决方案6】:

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

【讨论】:

  • 根据文档只能在客户端调用。它直接将用户注销,我认为在这种情况下不需要。
  • 确实 - 我正在尝试检测注销,而不是触发注销。
  • Meteor.logout 有一个回调函数 Meteor.logout(function(err){ //do stuff here }})
猜你喜欢
  • 2020-08-05
  • 1970-01-01
  • 2021-11-23
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
  • 2018-10-26
  • 2018-10-23
  • 2018-07-27
相关资源
最近更新 更多