且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

对管理员和普通用户使用相同身份验证方法时的用户冲突 |Firebase 身份验证

更新时间:2023-11-30 19:52:52

Firebase 不知道这里的管理员"是什么.这是一个特定于您的应用的概念,因此您必须执行它.

Firebase has no knowledge of what an "Admin" is here. That's a concept that is specific to your app, so you will have to enforce it.

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

There's no way to allow certain users to only sign in on a specific platform. This is because Firebase makes a clear split between authentication (the user proves who they are) and authorization (the user has access to a resource). You use Firebase Authentication for authenticating the users, but will the "who can use what app" is an authorization problem, so it is handled elsewhere.

如果您通过 Firebase 使用实时数据库、Cloud Firestore 或 Cloud Storage,例如,您通常会在 Firebase 的 服务器端安全规则.由于这些是在服务器上自动强制执行的,因此用户无法绕过它们,无论用户在哪个平台上,它们都同样适用.

If you're using Realtime Database, Cloud Firestore, or Cloud Storage through Firebase, you'll for example typically enforce our authorization logic in Firebase's server-side security rules. Since these are automatically enforced on the server, there's no way for a user to bypass them, and they apply equally no matter what platform the user is on.

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

For example, a common first security rule that I start my Firestore projects with is:

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 脚本的初始数据安全地填充我的数据库(在我最常见的情况下).

This allows anyone to read the data, and no-one to write it, since isAdmin always returns false. With these rules the only way I can write data is by using an Admin SDK, since code using this SDK runs with elevated privileges and bypasses the security rules. A perfect way to get started, and safely populate my database with initial data from Node.js scripts (in my most common case).

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

Then at some point I do as you did, and add an application administrator. At that point I add their UID to the security rules:

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

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

So the above function in my rules now gives two specific Firebase Authentication users write access to the data.

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

This approach works well for the first few users, but at some point adding UIDs to the rules gets tedious and error prone. At that point I have two main options:

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

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

For storing the UIDs in the database you'd typically either add those UIDs to the database manually, or allow administrators to identify other administrators, and write their UIDs from the app. Either way, the security rules for this are something like:

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

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

So the last line now also recognizes any authentication user whose UID is store in the admins collection as an application administrator.

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

Finally, say that I want everyone from my company to be an application administrator; I'd do that with:

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 身份验证用户现在也是应用程序管理员.

So this means that any Firebase Authentication user who has a verified @google.com email address is now an also application administrator.

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

As you can see, I build these rules up in multiple steps, starting with simply identifying that I will have application administrators who have specific permissions and creating the isAdmin function.