2014-01-23 50 views
5

我希望新的会议基本上“注销”任何以前的会话。例如,当您在一台计算机中进行经过身份验证的会话时,在另一台计算机上启动新会话并使用我们的应用上的Firebase进行身份验证时,会在第一台计算机上注销其他会话。如何防止同一用户同时登录Firebase?

我一直未能找到任何方法让我“远程”退出会话。我知道我可以在会话中使用unauth()和goOffline()。但是,如何从同一用户的不同身份验证会话中执行此操作?

感谢您的帮助!

背景资料:

  1. 我使用简单的电子邮件/密码登录的火力认证
  2. 我没有安全规则设置的是,虽然这是在作品
  3. 我m使用JavaScript和Firebase
+0

打开新选项卡仍被视为同一浏览器会话。我不认为你可以做到这一点,而无需将用户从两个选项卡中删除。您可以处理不同的浏览器。 – jammykam

+0

谢谢jammykam,我可以在同时进行的会话中打开两个选项卡。但是两个不同的浏览器(在两台不同的计算机上)就是我想要避免的。 – jdchizzle

回答

8

一般的想法是,你想在Firebase中创建一些元数据,告诉你有多少位置用户已登录。那么你可以使用这些信息限制他们的访问。

要做到这一点,您需要生成自己的令牌(以便信息可用于您的安全规则)。

1)生成令牌

使用custom login生成自己的令牌。每个标记应该包含一个唯一的ID为客户端(IP地址UUID?)

var FirebaseTokenGenerator = require("firebase-token-generator"); 
var tokenGenerator = new FirebaseTokenGenerator(YOUR_FIREBASE_SECRET); 
var token = tokenGenerator.createToken({ id: USER_ID, location_id: IP_ADDRESS }); 

2)使用存在于存储用户的LOCATION_ID

退房有关详细信息,managing presence底漆:

var fb = new Firebase(URL); 

// after getting auth token back from your server 
var parts = deconstructJWT(token); 
var ref = fb.child('logged_in_users/'+token.id); 

// store the user's location id 
ref.set(token.location_id); 

// remove location id when user logs out 
ref.onDisconnect().remove(); 

// Helper function to extract claims from a JWT. Does *not* verify the 
// validity of the token. 
// credits: https://github.com/firebase/angularFire/blob/e8c1d33f34ee5461c0bcd01fc316bcf0649deec6/angularfire.js 
function deconstructJWT(token) { 
    var segments = token.split("."); 
    if (!segments instanceof Array || segments.length !== 3) { 
    throw new Error("Invalid JWT"); 
    } 
    var claims = segments[1]; 
    if (window.atob) { 
    return JSON.parse(decodeURIComponent(escape(window.atob(claims)))); 
    } 
    return token; 
} 

3)添加安全规则

在安全规则,强制执行,只有当前独特的地理位置可以读取数据

{ 
    "some_restricted_path": { 
    ".read": "root.child('logged_in_users/'+auth.id).val() === auth.location_id" 
    } 
} 

4)logged_in_users

你要设置控制对logged_in_users写访问的某些系统控制的写访问。显然用户应该只能写自己的记录。如果您希望第一次登录尝试始终获胜,那么使用".write": "!data.exists()"

时,如果存在值(直到他们注销),请防止写入但是,通过允许最后一次登录获胜可以大大简化,在这种情况下,它会覆盖旧的位置值和以前的登录将失效并且无法读取。

5)这不是一个解决方案来控制你不能使用该功能防止多向并行注解你的火力地堡并行注解

的数量。请参阅goOffline()和goOnline()以获取更多有关完成此操作的数据(或者获得付费计划,以免对连接造成困难)。

+0

感谢您提供非常详细的解决方案。目前,我正在将个人用户的数据直接写入通过其转义电子邮件地址索引的Firebase中。将location_ID写入通过简单的电子邮件/密码登录生成的UID键(在其电子邮件地址索引表下),并使用该标识符来控制写入访问(而不是自定义安全令牌),可以吗? – jdchizzle

+0

简单登录可以区分不同位置的用户。由于标记中没有任何内容,因此您需要创建自己的标记才能使其适用于安全规则。 – Kato

相关问题