问题是关于下面扩展的船舶分支。只有经过身份验证的用户才能在任何地方写入 OWN 数据。但是,有一个例外。 任何经过身份验证的用户可以读取来自船舶分支的数据。
到目前为止,我没有遇到任何麻烦,但这是一条特殊规则:
如果时间戳为10秒或更早,任何经过身份验证的用户都可以删除船舶分支中任何uid下的子项。
我希望任何用户都可以致电:
firebase.database().ref('/ships/gp3tJa3tgThukt39EejqJpZq12L2/granit').remove();
uid: gp3tJa3tgThukt39EejqJpZq12L2
shipid: granit
并且只被授予删除权。
为了检查记录的年龄,我将firebase.database.ServerValue.TIMESTAMP
存储在索引perf
的0
数组中(我在这里使用数组,因为此记录经常出现更新,我希望将数据保持在最低限度)。
在客户端,程序可以查看记录何时可能已过期,然后才调用remove。这是为了避免浪费失败的电话。
我需要一些帮助来定义正确的规则。有问题的行在第二个示例中突出显示,我尝试定义此规则。
{
"ships": {
"EnBawzb0CjZVgAKrMZD4HE3k5rW2": {
"oasisoftheseas": {
"param": {
"scale": 0.33075936163570846,
"type": "cruise/royalcaribbean/oasisoftheseas"
},
"perf": {
"0": 1,
"1": 1.11014724E7,
"2": 1.70473256E7,
"3": 115.7,
"timeStamp": 1475144447302
}
}
},
"gp3tJa3tgThukt39EejqJpZq12L2": {
"granit": {
"param": {
"scale": 0.12235531736978282,
"type": "riverbarge/granit"
},
"perf": {
"0": 5,
"1": 2.05622392E7,
"2": 13154087,
"3": 285.9,
"timeStamp": 1475144450086
}
}
}
}
}
规则以下。我有兴趣正确定义$ shipid的写规则。
{
"rules": {
"anchors": {
"$uid":{
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
},
"completed": {
"$uid":{
".read": "auth.uid === $uid",
".write": "auth.uid == $uid"
}
},
"ships": {
".read": "auth !== null",
"$uid":{
".write": "auth.uid === $uid",
"$shipid":{
".write": "((auth !== null) &&
(now - data.child('perf').child('timeStamp').val() >= 10000))"
}
}
},
"shipslog": {
"$uid":{
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
}
}
}
答案 0 :(得分:1)
好吧,我发现弗兰克证实了这一点。在问题中编辑的解决方案是正确,安全和有效的。
"ships": {
".read": "auth !== null",
"$uid":{
".write": "auth.uid === $uid",
"$shipid":{
".write": "((auth !== null) &&
(now - data.child('perf').child('timeStamp').val() >= 10000))"
}
}
},...
任何数据都可以由记录所有者写入船舶分支。在更深层次上,我使用uid通配符和shipid通配符来获取可能过期且需要删除的数据。
时间戳是安全的,因为它是由服务器端的服务器提供的。删除船舶只能由任何经过身份验证的用户进行,并且只要现在和时间戳之间的差异大于10000毫秒。
这可能是让客户端应用程序清理旧数据而不需要服务器端业务逻辑的一种很好的通用方法。