Firebase中的onDisconnect()不可靠

时间:2016-06-06 21:43:11

标签: firebase firebase-realtime-database firebase-authentication

我在JavaScript中编写了以下简单的状态代码(基于https://firebase.google.com/docs/database/web/offline-capabilities#section-sample):

var app = firebase.initializeApp(config);
var mainRef = app.database().ref();
var session = null;
var connected = false;

function do_sessionSubscribe(subscription) {
    if (!subscription.entry) {
        subscription.entry = subscription.parent.push(true);
        subscription.entry.onDisconnect().remove();
    }
}

function do_sessionUnsubscribe(subscription) {
    if (subscription.entry) {
        subscription.entry.remove();
        subscription.entry = null;
    }
}

mainRef.child(".info/connected").on("value", function(snap) {
    connected = snap.val() === true;
    if (session) {
        if (connected) {
            do_sessionSubscribe(session.subscription);
        } else {
            // workaround
            //do_sessionUnsubscribe(session.subscription);
        }
    }
});

function closeSession() {
    if (session) {
        do_sessionUnsubscribe(session.subscription);
        session = null;
    }
}

function openSession(uid) {
    session = { uid: uid, subscription: { parent: mainRef.child("session/user/" + uid), entry: null } };
    if (connected) {
        do_sessionSubscribe(session.subscription);
    }
}

app.auth().onAuthStateChanged(function(user) {
    closeSession();
    if (user && user.uid) {
        openSession(user.uid);
    }
});

安全规则:

"session": {
    "user": {
        "$uid": {
            ".read": "auth.uid === $uid",
            ".write": "auth.uid === $uid",
            "$session": {
                ".validate": "newData.val() === true"
            }
        }
    },
}

这个想法是,用户的每个活动连接都会在连接/登录时创建/session/user/$uid/$session,并在断开/注销时删除它。

因此,为了获得在线用户列表,只需/session/user shallow=true就可以了。

问题在于有时会话未被清理并永远保持在/session/user/$uid之下。然后将其解释为如果用户始终在线。

我发现为了轻松重现问题,阻止访问securetoken.googleapis.com(我使用Google身份验证)就足够了,等一个小时然后关闭浏览器。

我尝试通过在断开连接时调用remove()来解决此问题。一旦客户端重新连接,这就清理了陈旧的会话(这太晚了,但迟到总比没有好......)。但是,当用户在断开互联网连接后关闭浏览器,然后在套接字超时之前,身份验证令牌过期,过时的会话将永远存在。

  1. 当用于注册onDisconnect()操作的auth令牌已经过期时,在检查安全规则期间使用了什么auth.uid值?
  2. 如何在不影响安全性的情况下使此展示系统完全可靠?

0 个答案:

没有答案