首页 >web前端 >js教程 >NgSysV.A Serious Svelte InfoSys:Firebase D/b 规则和登录

NgSysV.A Serious Svelte InfoSys:Firebase D/b 规则和登录

Patricia Arquette
Patricia Arquette原创
2024-11-29 08:49:10969浏览

NgSysV.A Serious Svelte InfoSys: Firebase D/b rules and Login

此帖子系列已在 NgateSystems.com 建立索引。您还可以在那里找到超级有用的关键字搜索工具。

最后评论:24 年 11 月

一、简介

当您在 2.3 版的帮助下创建第一个 Firestore 数据库时,您可能还记得系统询问您是否要应用“生产”规则或“测试”规则。当时的建议是应该选择“测试”规则。如果您此时使用 Firebase 控制台中 Firestore 页面上的“规则”选项卡,您会发现您的规则设置为如下所示:

match /{document=**} {
  allow read, write: if request.time 



<p>在这里,Google 创建了一条默认规则,该规则使用时间戳来允许从您创建数据库之日起 30 天内对您的数据库进行读写访问。这不太可能是你现在想要的(谷歌无论如何都会催促你改变它)。因此,现在是时候详细了解 Firestore 规则以及如何使用它们来确保数据库安全。</p>

<h3>
  
  
  数据库规则
</h3>

<p>Firestore“规则”允许您通过引用每当进行数据库调用时传递到 Firestore“规则处理程序”的 Firebase 请求对象来限制对数据库集合的读写访问。该对象包含发出请求的用户的详细信息、正在执行的操作类型以及当前时间等。如果您想查看完整的属性列表,chatGPT 将很乐意提供。 </p>

<p>要全面了解 Firestore 规则语法,最好建议您参阅 Google 自己的文档 Firestore 规则入门。就目前而言,我将重点关注本系列文章创建的默认数据库的直接要求。</p>

<p>要查看正在运行的数据库规则,请尝试使用 Firebase 控制台中 Firestore 页面上的“规则”选项卡将规则更改为:<br>
</p>

<pre class="brush:php;toolbar:false">    match /{document=**} {
      allow read: if true;
      allow write: if request.time 



<p>如果时间早于 2000 年 1 月 1 日,此规则仅允许对数据库中的文档进行写访问。因此,除非您当前正在时间机器中运行,否则您现在将无法创建新的时间机器文档。</p>

<p>点击“发布”按钮使新规则生效(您可以放心地忽略发布可能需要一些时间才能生效的消息 - 实际上延迟似乎很小),并查看您的网络应用程序的反应</p>

<p>启动您的开发服务器并在 http://localhost:5173 启动 Web 应用程序。当您尝试添加新产品时,当您收到“500:内部错误”页面时,您不应该感到太惊讶。当您进入终端会话调查原因时,您将看到以下消息:<br>
</p><pre class="brush:php;toolbar:false">match /{document=**} {
  allow read, write: if request.time 



<p>现在您已经了解了 Firestore 规则的工作原理,您可以开始考虑如何在您在 Post 3.1 中创建的产品显示和产品维护页面上使用它。</p>

<p>您可能还记得,它们提供了以下两条路线:</p>

  • 位于 localhost:5173/products-display 的“products-display”路由,允许用户读取产品集合中的所有文档,并且
  • 位于 localhost:5173/products-maintenance 的“products-maintenance”路由,允许用户将新文档写入集合。

假设,虽然您很乐意允许任何人使用“产品展示”路线阅读产品文档,但您只希望授权个人能够使用“产品维护”路线添加新产品。

个人将被授权,通过向他们颁发可用于“登录”网络应用程序的“用户 ID/密码”组合。此过程将在用户的客户端设备上创建持久的“身份验证”状态,该状态将成为 Firebase 请求对象的一部分,当用户尝试访问数据库时,该状态会传递到 Firestore 规则处理。

然后,如果您按如下方式设置 Firestore 规则:

    match /{document=**} {
      allow read: if true;
      allow write: if request.time 



<p>只有“登录”用户才能写入“产品”页面。 </p>

<p>现在您需要知道的是如何编写“登录”页面来创建身份验证状态。请继续阅读!</p>

<h3>
  
  
  2.Firebase登录
</h3>

<p>在登录屏幕中,潜在的系统用户被要求提供个人标识符(通常是电子邮件地址)和关联的密码。 </p>

<p>然后系统会根据已知凭据的安全列表检查用户的标识符和密码。在 Firebase 中,您可以在项目的 Firebase 控制台的“构建 -> 身份验证 -> 用户”选项卡下找到此列表。看看这个。借此机会注册测试电子邮件地址和密码(也可以进行“程序化”注册,但此处未介绍)。请注意 Firebase 分配给注册的“用户 UID 字段”。这是电子邮件地址的唯一加密版本。正如您很快就会看到的,这构成了 Firebase 安全机制的一个重要元素。另请注意,屏幕提供了删除帐户和更改密码的功能。</p>

<p>当您在这里时,请查看“身份验证”屏幕上的“登录方法”选项卡。提供电子邮件/密码组合或 Google 帐户。我建议您在此阶段仅启用电子邮件/密码选项。 </p>

<p>现在创建一个登录屏幕。下面显示的示例代码非常简短(而且大部分都是样式!):<br>
</p>

<pre class="brush:php;toolbar:false">[FirebaseError: Missing or insufficient permissions.] {
  code: 'permission-denied',
  customData: undefined,
  toString: [Function (anonymous)]
}

为登录和注销脚本创建新的路由文件夹和 page.svelte 文件。但先不要尝试运行它们,因为我需要告诉您更多的细节!

请注意,这些文件现在从中央 src/lib/utilities/firebase-client.js 文件导入其 auth 变量。在其中,Web 应用程序提供其 firebase-config 密钥,以确保 Firebase 它有权创建 auth 对象。这是执行此操作的 src/lib/utilities/firebase-client.js 的更新版本。

match /{document=**} {
  allow read, write: if request.time 



<p>由于此处导出的 app、auth 和 db 变量在 Web 应用程序中广泛需要,因此通过在中心位置生成它们可以节省大量代码。  </p>

<p>但是这里的一些“bling”需要一些解释。</p>

<p>首先,您会注意到,我不再直接在代码中编写 apiKey 等 firebaseConfig 属性<strong></strong>,而是引用我在项目的 .env 文件(一个文件)中定义的 Vite 参数或带有“.”的文件夹表示它是“系统”数据)。这是:<br>
</p>

<pre class="brush:php;toolbar:false">    match /{document=**} {
      allow read: if true;
      allow write: if request.time 



<p>.env 文件的全部要点是将 firebaseConfig 键放入不包含应用程序代码的文件中。这使您可以更轻松地管理其安全性。但现在让我们把它放在一边,这样您就可以专注于更重要的事情。我在这篇文章的末尾添加了一条注释,希望能解释一切。</p>

<p>第二个可能让您困惑的功能是 const app = !getApps().length ?初始化应用程序(firebaseConfig):getApp();线。这是 Javascript“三元”语句的示例(如果您以前没有遇到过这一点,请使用 chatGPT 来解释它是如何工作的)。它的作用是:</p>

  • 仅当 Firebase 环境中当前不存在任何应用时才初始化 Firebase 应用。 Web 应用程序将在用户会话期间频繁引用 firebase-client.js,如果应用程序已存在,则initializeApp() 会失败
  • 否则检索现有应用程序。

现在回到主流,所有这一切的效果是,当登录成功时,Firebase 为经过身份验证的用户创建一个“auth”对象,并将其安全地存储在浏览器环境中。因此,Firebase 可以自动将由此生成的身份验证令牌添加到传递给 FireStore 数据库服务请求的每个请求对象。令牌中的信息包括您之前在 Firebase 身份验证选项卡中看到的“用户 uID”标识符等属性。因此,Firestore 可以决定如何应用规则,例如允许写入:if request.auth != null。

这一切都意味着客户端 Firestore 活动就像发条一样工作 - 一旦您登录,Firestore 规则就会处理您所有的数据库安全问题。

但是有一个障碍——事实上,一个巨大的障碍。 Firebase 嵌入浏览器环境的“auth”对象不可用于服务器端页面,例如 inventory-maintenance/page.server.js。

您可以轻松地演示这一点。

  1. 发布新的 Firestore 规则,让任何人读取产品集合中的所有内容,但确保只有经过身份验证的人员可以编写文档

    match /{document=**} {
      allow read, write: if request.time 
    
    
  2. 使用 /login 路由登录并收到“您已使用 Google 登录”警报。

  3. 启动 /products-display 页面。因为 Firestore 规则允许任何人阅读所有内容。因此,该页面将像以前一样显示当前已注册产品的列表。

  4. 尝试使用产品维护页面添加新产品。啊啊!错误!

    match /{document=**} {
      allow read: if true;
      allow write: if request.time 



<p>此处发生的情况是,浏览器的“squirrelled”auth 变量及其父 Firebase 会话信息的其余部分对于服务器上的 Firestore 不可用。因此 request.auth 在那里未定义,因此 Firestore 规则失败。 </p>

<p>Google 的立场是拒绝向 Firebase 提供出色的会话管理工具的服务器端版本,该工具使客户端的生活变得如此愉快。目前,您的代码一直在使用 Firestore <strong>Client</strong> API。在服务器上,如果 Firestore 数据库在引用 Firebase 身份验证会话变量的集合上设置了“规则”,则您必须使用 Firestore <strong>Admin</strong> API 而不是客户端 API。管理 API 中的调用不会检查 Firestore 规则,因此在未定义身份验证时不会失败。但使用 Admin API 会产生几个后果:</p>

  • 管理 API 使用不同的“调用签名”。用于在服务器端执行读/写数据库操作的管理 API 函数序列与客户端版本大致相似,但使用不同的语法。
  • 管理 API 要求您使用自己编写的代码获取可能需要的任何用户数据。客户端 Firebase 会话可以方便地提供宝贵的 auth.currentUser 对象来传递 uID 和 userName 等,但在服务器端不再可用。您必须自行安排更换。

呻吟。还有其他选择吗?接下来的两篇文章显示:

  1. 如何通过开发 Web 应用程序的“规则友好”版本来避免这个问题。这样做的后果将是性能较差(因为服务器端代码运行速度更快)、安全性降低(因为客户端表单验证不安全)以及 SEO 前景下降(因为网络蜘蛛降低了对客户端代码建立索引的热情)
  2. 或者,您可以如何开发一个完整的“客户端-服务器”版本的网络应用程序。这将为您提供一流的性能、安全性和 SEO,但需要您协商另一波技术来填补因 Firebase 用户会话安排丢失而留下的功能空白

三、结论

这是一段艰难的旅程,结局并不美好。不过,我希望你有精力继续阅读。

从您作为开发人员的角度来看,规则友好的代码将是一个完美的乐趣,因为您可以完全使用浏览器的检查器工具来调试它。虽然它有局限性,如前所述,但它对于许多简单的应用程序来说可以完全令人满意。

或者,虽然客户端-服务器版本带来了一些新的挑战,但它将为您提供主流开发实践中的宝贵经验,并提供真正卓越的性能。

后记 - 这个“.env”业务到底是怎么回事?

虽然看起来很奇怪,但这一切都始于微软的“Github”版本控制软件。这是一个免费的网络应用程序,可让您将源副本复制到个人基于网络的存储库中。它已成为行业标准,您可以在 git 和 Github 的温和介绍中了解它。

其主要目的是整合在同一项目上并行工作的开发团队的活动。但是可能会对使用它很感兴趣,因为在您的个人项目的开发和持续增强过程中,有时您希望将代码的“检查点”快照放置在安全的地方。 .

问题在于,源代码中嵌入的敏感密钥很容易被无意中保存在 Git 存储库中。虽然存储库可以标记为“私有”,但安全性无法得到保证。

答案的一部分是进行安排,以便项目密钥与代码文件分开保存。这样它们就不需要需要复制到Git。将 Firebase 密钥放入 libutilitiesfirebase-client.js 文件中会有所帮助,因为这意味着密钥不再编码到多个 page.server.js 文件中。但是中央 firebase-client.js 中仍然有您希望保存在存储库中的代码。使用 env 文件可以让您最终将代码与键分开。尽管您的 .env 密钥保留在项目中,但不再需要将该文件复制到代码存储库。因此,可以将其添加到 .gitignore 文件中,该文件告诉 Git 要排除哪些文件。

您会发现 Svelte 在初始化您的项目时创建了一个 .gitignore 文件,并且它已经包含在源代码检查点中没有位置的 Vite 系统文件夹的详细信息。为了确保“.env”文件(以及该文件的任何编辑历史记录)从所有 Git 提交中排除,您需要添加以下条目:

match /{document=**} {
  allow read, write: if request.time 



<p><em>请注意,完成此操作后,VSCode 工作区目录中的 /.env 行将变为“灰色”。这提供了视觉保证,确保该文件不会通过 Git 提交在网络上公开。</em></p>


          

            
        

以上是NgSysV.A Serious Svelte InfoSys:Firebase D/b 规则和登录的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn