【问题标题】:User conflict when using same Auth method for Admin and Normal users | Firebase Auth对管理员和普通用户使用相同的身份验证方法时的用户冲突 | Firebase 身份验证
【发布时间】:2020-02-28 10:08:41
【问题描述】:

我正在开发一个 android 应用程序的管理模块。管理模块是一个基于 Angular 的网络应用程序。 Firebase auth(Email/password) 用于以管理员身份登录。我已经向 firebase 添加了一个手动凭据条目,管理员正在使用这些凭据登录(因为管理员没有注册功能)

另一方面,Android 开发人员也使用相同的 Auth 方法来登录用户。因此,android 应用程序的用户可以使用他们的凭据登录到管理模块。

如何防止安卓用户登录网络应用。是否有任何方法或规则可用于过滤传入的登录请求并仅在电子邮件属于管理员时才允许登录?

【问题讨论】:

    标签: firebase firebase-authentication firebase-security angularfire


    【解决方案1】:

    Firebase 不知道这里的“管理员”是什么。这是一个特定于您的应用的概念,因此您必须强制执行。

    无法允许某些用户仅在特定平台上登录。这是因为 Firebase 明确区分了身份验证(用户证明他们是谁)和授权(用户有权访问资源)。您使用 Firebase 身份验证来对用户进行身份验证,但是“谁可以使用什么应用程序”是一个授权问题,所以它在其他地方处理。

    如果您通过 Firebase 使用实时数据库、Cloud Firestore 或 Cloud Storage,您通常会在 Firebase 的 server-side security rules 中强制执行我们的授权逻辑。由于这些是在服务器上自动执行的,因此用户无法绕过它们,并且无论用户使用什么平台,它们都同样适用。


    例如,我启动 Firestore 项目时常用的第一条安全规则是:

    service cloud.firestore {
      match /databases/{database}/documents {
        match /chat/{document} {
          allow read;
          allow write: 
            if isAdmin()
        }
    
        function isAdmin() {
          return false;
        }
      }
    }
    

    这允许任何人读取数据,而没有人可以写入数据,因为isAdmin 总是返回 false。使用这些规则,我可以编写数据的唯一方法是使用 Admin SDK,因为使用此 SDK 的代码以提升的权限运行并绕过安全规则。一种完美的入门方式,并使用来自 Node.js 脚本的初始数据安全地填充我的数据库(在我最常见的情况下)。


    然后在某个时候我会像你一样,添加一个应用程序管理员。那时我将他们的 UID 添加到安全规则中:

        function isAdmin() {
          return request.auth.uid == "KqEizsqUQ6XMkUgLUpNxFnzLm4F3"
              || request.auth.uid == "zYXmog8ySOVRrSGVt9FHFr4wJb92";
        }
    

    因此,我的规则中的上述函数现在为两个特定的 Firebase 身份验证用户提供了对数据的写入权限。


    这种方法适用于最初的少数用户,但在某些时候将 UID 添加到规则中会变得乏味且容易出错。那时我有两个主要选择:

    1. 将应用程序管理员的 UID 存储在数据库中。
    2. 以另一种方式识别应用程序管理员。

    为了将 UID 存储在数据库中,您通常需要手动将这些 UID 添加到数据库中,或者允许管理员识别其他管理员,然后从应用程序中写入他们的 UID。无论哪种方式,安全规则都类似于:

    function isAdmin() {
      return request.auth.uid == "KqEizsqUQ6XMkUgLUpNxFnzLm4F3"
          || request.auth.uid == "zYXmog8ySOVRrSGVt9FHFr4wJb92"
          || exists(/databases/$(database)/documents/admins/$(request.auth.uid))
          ;
    }
    

    所以最后一行现在也将 UID 存储在 admins 集合中的任何身份验证用户识别为应用程序管理员。

    最后,说我希望我公司的每个人都成为应用程序管理员;我会这样做:

    function isAdmin() {
      return request.auth.uid == "KqEizsqUQ6XMkUgLUpNxFnzLm4F3"
          || request.auth.uid == "zYXmog8ySOVRrSGVt9FHFr4wJb92"
          || (request.auth.token.email_verified && request.auth.token.email.matches(".*@google.com"))
          || exists(/databases/$(database)/documents/admins/$(request.auth.uid))
          ;
    }
    

    这意味着任何拥有经过验证的@google.com 电子邮件地址的 Firebase 身份验证用户现在也是应用程序管理员。


    如您所见,我通过多个步骤构建这些规则,首先简单地确定我将拥有具有特定权限的应用程序管理员并创建 isAdmin 函数。

    【讨论】:

      猜你喜欢
      • 2011-11-30
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 2016-04-19
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      相关资源
      最近更新 更多