问题描述
限时送ChatGPT账号..在尝试不同的、各种推荐的方法来做到这一点之后,我确实花了几天的时间,终于找到了我认为最简单、最有前途的方法.还要感谢这个问题的好心人:,这建议将社交网络附加到 ID.文档希望您为每个登录方法的 ID 创建不同的规则.为什么任何使用 >1 种登录方法的人都想这样做,这超出了我的理解.
(来自:https://www.firebase/docs/security/rule-expressions/auth.html)
因此,我将尝试将连接后的 auth.provider
与 auth.id
与 userId
中的记录进行匹配,以获得相应的 注册表
项.
根据 API,这应该是很简单
在我的情况下,当然使用 $registry
而不是 $user
.
<代码>{规则":{.read":对,.write":对,注册表":{$注册表":{".read": "$registry == auth.id"}}}}
但这行不通,因为(参见上面的第一张图片),AngularFire 将每个记录设置在一个索引值下.在上图中,它是 0
.这就是事情变得复杂的地方.
此外,我无法在模拟器中测试任何内容,因为我无法编辑 {some: 'json'}
甚至进行身份验证.输入框拒绝任何输入.
我最好的猜测如下.
<代码>{规则":{.write":对,注册表":{$注册表":{".read": "data.child('userId').val() == (auth.provider + auth.id)"}}}}
这既会引发身份验证错误,又会同时向所有用户授予完全读取权限.我正在失去理智.我应该在这里做什么?
解决方案forge 模拟器中的自定义 Auth 并不是最好的,但是如果您在选择输入后点击 Tab 键,它可以让您粘贴或编辑该字段.此时您可以添加 {"provider":"facebook","id":"63203497"}
或 {"provider":"twitter","id":"2934392"}
并希望从中得到一些有用的调试.
假设您的 Firebase 类似于:
{"注册表":{0":{"id":"abbacadaba123","索引":"0","name":"新设备","userId":"facebook63203497"},1":{"id":"adaba123","索引":"1","name":"其他设备","userId":"twitter2934392"}}}
这可能适用于安全规则:
<代码>{规则":{注册表":{$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()"},指数": {".validate":"newData.isNumber()"},姓名": {".validate":"newData.isString() && newData.val().length >= 1"},用户身份": {".validate":"newData.val() === (auth.provider + auth.id)"}}}}}
您的阅读规则已按预期测试.facebook 用户在注册表 0 上读取测试为真,在 1 上为假. twitter 用户在 0 上为假,在 1 上为真.我对 .write 和 .validate 规则进行了几次快速测试,它们似乎有效.
希望这至少有助于排除 firebase 安全规则部分,因此您可以专注于 AngularFire 绑定部分.
Having spent literally days trying the different, various recommended ways to do this, I've landed on what I think is the most simple and promising. Also thanks to the kind gents from this SO question: Get the index ID of an item in Firebase AngularFire
Curent setup
Users can log in with email and social networks, so when they create a record, it saves the userId
as a sort of foreign key.
Good so far. But I want to create a rule so twitter2934392
cannot read facebook63203497
's records.
Off to the security panel
Match the IDs on the backend
Unfortunately, the docs are inconsistent with the method from is firebase user id unique per provider (facebook, twitter, password) which suggest appending the social network to the ID. The docs expect you to create a different rule for each of the login method's ids. Why anyone using >1 login method would want to do that is beyond me.
(From: https://www.firebase/docs/security/rule-expressions/auth.html)
So I'll try to match the concatenated auth.provider
with auth.id
to the record in userId
for the respective registry
item.
According to the API, this should be as easy as
In my case using $registry
instead of $user
of course.
{
"rules": {
".read": true,
".write": true,
"registry": {
"$registry": {
".read": "$registry == auth.id"
}
}
}
}
But that won't work, because (see the first image above), AngularFire sets each record under an index value. In the image above, it's 0
. Here's where things get complicated.
Also, I can't test anything in the simulator, as I cannot edit {some: 'json'}
To even authenticate. The input box rejects any input.
My best guess is the following.
{
"rules": {
".write": true,
"registry": {
"$registry": {
".read": "data.child('userId').val() == (auth.provider + auth.id)"
}
}
}
}
Which both throws authentication errors and simultaneously grants full read access to all users. I'm losing my mind. What am I supposed to do here?
解决方案The custom Auth in the forge's simulator isn't the greatest but if you hit the tab key after selecting the input, it lets you paste or edit the field. At which point you can add {"provider":"facebook","id":"63203497"}
or {"provider":"twitter","id":"2934392"}
and hopefully get some useful debug out of it.
Assuming your firebase is something like:
{"registry":{
"0":{
"id":"abbacadaba123",
"index":"0",
"name":"New Device",
"userId":"facebook63203497"},
"1":{
"id":"adaba123",
"index":"1",
"name":"Other Device",
"userId":"twitter2934392"}
}
}
This may work for security rules:
{
"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)"
}
}
}
}
}
Your read rule tested as expected. The facebook user read-tests true on registry 0 and false on 1. The twitter user is false on 0 and true on 1. I did a couple quick tests on the .write and .validate rules and they seem to work.
Hope this helps at least rule out the firebase security rules portion of things, so you can focus on the AngularFire binding part.
这篇关于使用 AngularFire 中的记录进行基本用户身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论