代码之家  ›  专栏  ›  技术社区  ›  Theo

如何限制实时数据库中特定节点下声明的用户的写访问权限

  •  0
  • Theo  · 技术社区  · 6 年前

    我在我的应用程序中发现了一些奇怪的东西。首先,我注册。

    enter image description here

    然后进入欢迎屏幕。

    enter image description here

    为了验证我确实在firebase中注册,我进入控制台。身份验证中的第一位

    enter image description here

    然后在数据库中,您会看到一个名为Users的节点(我注册时声明为Users)。

    enter image description here

    但是假设我不小心从数据库中删除了这个用户。用户仍在登录该应用程序,并试图对文章发表评论。显然,会有回应,

    E/CommentActivity: User AhtNY3bm7aQdPiJewf3PBN310732 is unexpectedly null
    

    这来自这里。

    User user = dataSnapshot.getValue(User.class);
    
                        // [START_EXCLUDE]
                        if (user == null) {
                            // User is null, error out
                            Log.e(TAG, "User " + userId + " is unexpectedly null");
                            Toast.makeText(CommentActivity.this,
                                    "Error: could not fetch user.",
                                    Toast.LENGTH_SHORT).show();
                        }
    

    CommentActivity的整个代码是 here .

    有没有办法避免这种错误?我的意思是,一旦用户在firebase中注册,即使他被意外删除,他也可以发表评论。也许可以在这里使用任何setter/getter方法?

    public class User {
    
    public String username;
    public String email;
    
    
    public User() {
        // Default constructor required for calls to DataSnapshot.getValue(User.class)
    }
    
    public User(String username, String email) {
        this.username = username;
        this.email = email;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getEmail() {
        return email;
    }
    
    public void setEmail(String email) {
        this.email = email;
    }
    
    }
    

    使现代化

    我把这个规则

    {
      "rules": {
      ".read": "auth != null",
      ".write": "auth != null"
    },
    {
      "rules": {
      "comments": {
      ".write": "auth != null && root.child('Users').hasChild(auth.uid)"
      ".read": "auth != null"
      }
     }
     }  
    }
    

    但我有一个语法错误。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Renaud Tarnec    6 年前

    身份验证面板中用户的存在与用户在 Users 节点,在数据库中。所以,就像你在帖子中提到的,如果你删除 user 节点,他/她仍将能够进行身份验证。

    因此,您必须使用专用的 安全规则 (将其视为 批准 整体的一部分 认证/授权 机制)。

    编写此数据库安全规则时,应确保用户的UID必须存在于 用户 节点允许他/她写“评论”,如下所示:

    {
      "rules": {
        "comments": {
          ".write": "auth != null && root.child('Users').hasChild(auth.uid)"
          ".read": ...
        }
      }
    }
    

    在这里,我们假设 comments 节点直接位于数据库根目录下。您可以根据自己的数据模型调整此规则(可能在该路径中包含post UID)。

    请查看相应的安全文档, here ,尤其是文档末尾的完整示例。