8
The general idea is that you want to create some meta data in Firebase which tells you how many locations a user is logged in from. Then you can restrict their access using this information.
一般的想法是,您希望在Firebase中创建一些元数据,它会告诉您一个用户从哪里登录了多少个位置。然后您可以使用这些信息限制他们的访问。
To do this, you'll need to generate your own tokens (so that the information is available to your security rules).
为此,您需要生成您自己的令牌(以便您的安全规则可以使用这些信息)。
1) Generate a token
1)生成一个令牌
Use custom login to generate your own tokens. Each token should contain a unique ID for the client (IP Address? UUID?)
使用自定义登录来生成您自己的令牌。每个令牌应该包含客户端的唯一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) Use presence to store the user's location_id
2)使用存在来存储用户的location_id。
Check out the managing presence primer for details:
详情请参阅管理存在入门:
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) Add security rules
3)添加安全规则
In security rules, enforce that only the current unique location may read data
在安全规则中,强制要求只有当前唯一位置可以读取数据
{
"some_restricted_path": {
".read": "root.child('logged_in_users/'+auth.id).val() === auth.location_id"
}
}
4) Control write access to logged_in_users
4)控制写访问logged_in_users。
You'll want to set up some system of controlling write access to logged_in_users. Obviously a user should only be able to write to their own record. If you want the first login attempt to always win, then prevent write if a value exists (until they log out) by using ".write": "!data.exists()"
您将需要设置一些系统来控制对logged_in_users的写访问。显然,用户应该只能写自己的记录。如果您希望第一次登录尝试总是成功,那么请使用“”来防止如果存在某个值(直到该值退出)的写操作。写”:“! data.exists()
However, you can greatly simplify by allowing the last login to win, in which case it overwrites the old location value and the previous logins will be invalidated and fail to read.
但是,您可以通过允许最后的登录获胜来极大地简化,在这种情况下,它将覆盖旧的位置值,而以前的登录将被无效并无法读取。
5) This is not a solution to control the number of concurrents
5)这不是一个控制电流数目的解决方案
You can't use this to prevent multiple concurrents to your Firebase. See goOffline() and goOnline() for more data on accomplishing this (or get a paid plan so you have no hard cap on connections).
你不能用这个来阻止你的火基的多个电流。查看goOffline()和goOnline()以获得更多关于完成此任务的数据(或者获得一个付费的计划,这样你就不会对连接进行硬性限制)。