Basic user authentication with records in AngularFire

早过忘川 提交于 2019-12-18 13:48:30

问题


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?


回答1:


I don't think you want to store user-specific data under a non-user-specific index. Instead of push()ing to your firebase reference, store the user data behind a meaningful key.

e.g.

auth.createUser(email, password, function(error, user) {
  if (!error) {
    usersRef.child(user.id).set(stuff);
  }
});

Now you can actually fetch user data based on who is authenticated.




回答2:


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.



来源:https://stackoverflow.com/questions/19481149/basic-user-authentication-with-records-in-angularfire

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!