一般的想法是,你想在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()以获取更多有关完成此操作的数据(或者获得付费计划,以免对连接造成困难)。
打开新选项卡仍被视为同一浏览器会话。我不认为你可以做到这一点,而无需将用户从两个选项卡中删除。您可以处理不同的浏览器。 – jammykam
谢谢jammykam,我可以在同时进行的会话中打开两个选项卡。但是两个不同的浏览器(在两台不同的计算机上)就是我想要避免的。 – jdchizzle