首頁 > web前端 > js教程 > NgSysV.A Serious Svelte InfoSys:Firebase D/b 規則與登入

NgSysV.A Serious Svelte InfoSys:Firebase D/b 規則與登入

Patricia Arquette
發布: 2024-11-29 08:49:10
原創
867 人瀏覽過

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 < timestamp.date(2024, 10, 31);
}
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

在這裡,Google 建立了一條預設規則,該規則使用時間戳來允許從您建立資料庫之日起 30 天內對您的資料庫進行讀寫存取。這不太可能是你現在想要的(谷歌無論如何都會催促你改變它)。因此,現在是時候詳細了解 Firestore 規則以及如何使用它們來確保資料庫安全。

資料庫規則

Firestore「規則」可讓您透過引用每當資料庫呼叫時傳遞到 Firestore「規則處理程序」的 Firebase 請求物件來限制對資料庫集合的讀寫存取。該物件包含發出請求的使用者的詳細資訊、正在執行的操作類型以及當前時間等。如果您想查看完整的屬性列表,chatGPT 將很樂意提供。

要全面了解 Firestore 規則語法,最好建議您參考 Google 自己的文件 Firestore 規則入門。就目前而言,我將重點放在本系列文章創建的預設資料庫的直接要求。

要查看正在執行的資料庫規則,請嘗試使用 Firebase 控制台中 Firestore 頁面上的「規則」標籤將規則變更為:

    match /{document=**} {
      allow read: if true;
      allow write: if request.time < timestamp.date(2000, 01, 01);
    }
登入後複製
登入後複製
登入後複製
登入後複製

如果時間早於 2000 年 1 月 1 日,此規則僅允許對資料庫中的文件進行寫入存取。因此,除非您目前正在時間機器中運行,否則您現在將無法建立新的時間機器文件。

點擊「發布」按鈕使新規則生效(您可以放心地忽略發布可能需要一些時間才能生效的消息 - 實際上延遲似乎很小),並查看您的網路應用程式的反應

啟動您的開發伺服器並在 http://localhost:5173 啟動 Web 應用程式。當您嘗試新增產品時,當您收到「500:內部錯誤」頁面時,您不應該感到太驚訝。當您進入終端會話調查原因時,您將看到以下訊息:

match /{document=**} {
  allow read, write: if request.time < timestamp.date(2024, 10, 31);
}
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

現在您已經了解了 Firestore 規則的工作原理,您可以開始考慮如何在您在 Post 3.1 中建立的產品顯示和產品維護頁面上使用它。

您可能還記得,它們提供了以下兩條路線:

  • 位於 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 < timestamp.date(2000, 01, 01);
    }
登入後複製
登入後複製
登入後複製
登入後複製

只有「登入」使用者才能寫入「產品」頁面。

現在您需要知道的是如何編寫「登入」頁面來建立身份驗證狀態。請繼續閱讀!

2.Firebase登入

在登入畫面中,潛在的系統使用者被要求提供個人識別碼(通常是電子郵件地址)和關聯的密碼。

然後系統會根據已知憑證的安全性清單檢查使用者的識別碼和密碼。在 Firebase 中,您可以在專案的 Firebase 控制台的「建置 -> 驗證 -> 使用者」標籤下找到此清單。看看這個。藉此機會註冊測試電子郵件地址和密碼(也可以進行「程序化」註冊,但此處未介紹)。請注意 Firebase 分配給註冊的「使用者 UID 欄位」。這是電子郵件地址的唯一加密版本。正如您很快就會看到的,這構成了 Firebase 安全機制的一個重要元素。另請注意,螢幕提供了刪除帳戶和更改密碼的功能。

當您在這裡時,請查看「身份驗證」畫面上的「登入方法」標籤。提供電子郵件/密碼組合或 Google 帳戶。我建議您在此階段僅啟用電子郵件/密碼選項。

現在建立一個登入畫面。下面顯示的範例程式碼非常簡短(而且大部分都是樣式!):

[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 < timestamp.date(2024, 10, 31);
}
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

由於此處匯出的 app、auth 和 db 變數在 Web 應用程式中廣泛需要,因此透過在中心位置產生它們可以節省大量程式碼。

但是這裡的一些「bling」需要一些解釋。

首先,您會注意到,我不再直接在程式碼中編寫apiKey 等firebaseConfig 屬性,而是引用我在專案的.env 檔案(一個檔案)中定義的Vite 參數或帶有“.”的資料夾表示它是“系統”資料)。這是:

    match /{document=**} {
      allow read: if true;
      allow write: if request.time < timestamp.date(2000, 01, 01);
    }
登入後複製
登入後複製
登入後複製
登入後複製

.env 檔案的全部重點是將 firebaseConfig 鍵放入不包含應用程式程式碼的檔案中。這使您可以更輕鬆地管理其安全性。但現在讓我們把它放在一邊,這樣您就可以專注於更重要的事情。我在這篇文章的末尾添加了一條註釋,希望能解釋一切。

第二個可能讓您困惑的功能是 const app = !getApps().length ?初始化應用程式(firebaseConfig):getApp();線。這是 Javascript「三元」語句的範例(如果您以前沒有遇到過這一點,請使用 chatGPT 來解釋它是如何運作的)。它的作用是:

  • 僅當 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 < timestamp.date(2024, 10, 31);
    }
    
    登入後複製
    登入後複製
    登入後複製
    登入後複製
    登入後複製
  2. 使用 /login 路由登入並收到「您已使用 Google 登入」警報。

  3. 啟動 /products-display 頁面。因為 Firestore 規則允許任何人閱讀所有內容。因此,該頁面將像以前一樣顯示目前已註冊產品的清單。

  4. 嘗試使用產品維護頁面新增產品。啊啊!錯誤!

    match /{document=**} {
      allow read: if true;
      allow write: if request.time < timestamp.date(2000, 01, 01);
    }
登入後複製
登入後複製
登入後複製
登入後複製

此處發生的情況是,瀏覽器的「squirrelled」auth 變數及其父 Firebase 會話資訊的其餘部分對於伺服器上的 Firestore 不可用。因此 request.auth 在那裡未定義,因此 Firestore 規則會失敗。

Google 的立場是拒絕向 Firebase 提供出色的會話管理工具的伺服器端版本,該工具使客戶端的生活變得如此愉快。目前,您的程式碼一直在使用 Firestore Client API。在伺服器上,如果 Firestore 資料庫在引用 Firebase 驗證會話變數的集合上設定了“規則”,則您必須使用 Firestore Admin API 而不是客戶端 API。管理 API 中的呼叫不會檢查 Firestore 規則,因此在未定義驗證時不會失敗。但使用 Admin API 會產生幾個後果:

  • 管理 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 < timestamp.date(2024, 10, 31);
}
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

請注意,完成此操作後,VSCode 工作區目錄中的 /.env 行將變為「灰色」。這提供了視覺保證,確保該文件不會透過 Git 提交在網路上公開。

以上是NgSysV.A Serious Svelte InfoSys:Firebase D/b 規則與登入的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板