花了几天时间尝试不同的,各种推荐的方法来实现这一目标,我已经着眼于我认为最简单和最有希望的方法。还要感谢这个SO问题的善意:Get the index ID of an item in Firebase AngularFire
Curent设置
用户可以使用电子邮件和社交网络登录,因此当他们创建记录时,会将userId
保存为一种外键。
到目前为止很好。但我想创建一条规则,因此twitter2934392
无法读取facebook63203497
的记录。
关闭安全面板
匹配后端的ID
不幸的是,文档与is firebase user id unique per provider (facebook, twitter, password)中建议将社交网络附加到ID的方法不一致。文档希望您为每个登录方法的ID创建不同的规则。为什么任何使用> 1登录方法的人都希望这样做超出我的范围。
(来自:https://www.firebase.com/docs/security/rule-expressions/auth.html)
因此,我会尝试将连接的auth.provider
与auth.id
匹配到userId
中相应registry
项的记录。
According to the API,这应该像
一样简单
在我的情况下,当然使用$registry
代替$user
。
{
"rules": {
".read": true,
".write": true,
"registry": {
"$registry": {
".read": "$registry == auth.id"
}
}
}
}
但这不起作用,因为(见上面的第一张图片),AngularFire将每条记录设置为索引值。在上图中,它是0
。事情变得复杂了。
另外,我无法在模拟器中测试任何内容,因为我无法编辑{some: 'json'}
甚至进行身份验证。输入框拒绝任何输入。
我最好的猜测如下。
{
"rules": {
".write": true,
"registry": {
"$registry": {
".read": "data.child('userId').val() == (auth.provider + auth.id)"
}
}
}
}
它们都会抛出身份验证错误并同时授予所有用户完全读取权限。我正在失去理智。我该怎么办?
答案 0 :(得分:0)
我认为您不希望在非特定于用户的索引下存储特定于用户的数据。而不是push()
到您的firebase引用,而是将用户数据存储在有意义的密钥后面。
e.g。
auth.createUser(email, password, function(error, user) {
if (!error) {
usersRef.child(user.id).set(stuff);
}
});
现在,您可以根据经过身份验证的人实际获取用户数据。
答案 1 :(得分:0)
伪造模拟器中的自定义Auth并不是最好的,但如果在选择输入后点击Tab键,则可以粘贴或编辑该字段。此时,您可以添加{"provider":"facebook","id":"63203497"}
或{"provider":"twitter","id":"2934392"}
,并希望从中获得一些有用的调试。
假设您的火力架类似于:
{"registry":{
"0":{
"id":"abbacadaba123",
"index":"0",
"name":"New Device",
"userId":"facebook63203497"},
"1":{
"id":"adaba123",
"index":"1",
"name":"Other Device",
"userId":"twitter2934392"}
}
}
这可能适用于安全规则:
{
"rules": {
"registry":{
"$registryId":{
".read":"data.child('userId').val() === (auth.provider + auth.id)",
".write":"(data.child('userId').val() === (auth.provider + auth.id))||(auth != null && !data.exists())",
".validate": "newData.hasChildren(['id', 'index', 'name', 'userId'])",
"id": {
".validate":"newData.isString()"
},
"index": {
".validate":"newData.isNumber()"
},
"name": {
".validate":"newData.isString() && newData.val().length >= 1"
},
"userId": {
".validate":"newData.val() === (auth.provider + auth.id)"
}
}
}
}
}
您的阅读规则按预期进行了测试。 facebook用户在注册表0上读取测试结果为真,在1上表示为false.twitter用户在0上为false,在1上为true。 我对.write和.validate规则进行了几次快速测试,它们似乎有效。
希望这有助于至少排除firebase安全规则部分,因此您可以专注于AngularFire绑定部分。