使用 AngularFire 中的记录进行基本用户身份验证 [英] Basic user authentication with records in AngularFire

查看:21
本文介绍了使用 AngularFire 中的记录进行基本用户身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试不同的、各种推荐的方法来做到这一点之后,我确实花了几天的时间,终于找到了我认为最简单、最有前途的方法.还要感谢这个问题的好心人:,这建议将社交网络附加到 ID.文档希望您为每个登录方法的 ID 创建不同的规则.为什么任何使用 >1 种登录方法的人都想这样做,这超出了我的理解.

(来自:https://www.firebase.com/docs/security/rule-expressions/auth.html)

因此,我将尝试将连接后的 auth.providerauth.iduserId 中的记录进行匹配,以获得相应的 注册表项.

根据 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.com/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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆