修正不安全的規則
請參閱本指南,瞭解 Firestore 安全性規則設定的常見安全漏洞、檢查並加強保護自己的規則,以及在部署變更前進行測試。
如果收到警示,指出原生模式的 Firestore 資料庫未妥善保護,您可以修改及測試 Firestore 安全性規則,解決安全漏洞。
如要查看現有的安全性規則,請前往 Firebase 控制台的「規則」分頁。
瞭解 Firestore 安全性規則
Firestore 安全性規則可保護資料免於惡意使用者侵擾。在 Firebase 控制台中建立的任何 Firestore (Native Mode) 執行個體,預設規則都會拒絕所有使用者存取。如要開發應用程式及存取資料庫,您需要修改這些規則,並考慮在開發環境中授予所有使用者全面存取權。不過,在將應用程式部署至正式環境之前,請花時間正確設定規則並保護資料。
開發應用程式並測試規則的不同設定時,請使用 Firestore 原生模式模擬器,在本機開發環境中執行應用程式。
安全性偏低的規則常見情境
如果您預設或在最初使用原生模式開發應用程式時設定了 Firestore 安全性規則,請務必在部署應用程式前檢查並更新這些規則,確保使用者資料受到妥善保護,避免發生下列常見錯誤。
公開存取
設定原生模式的 Firestore 時,您可能已將規則設為在開發期間允許開放存取。您可能以為只有自己會使用應用程式,但只要部署應用程式,網路上任何人都能存取。如果您未驗證使用者身分及設定安全規則,任何猜出專案 ID 的人都能竊取、修改或刪除資料。
不建議:所有使用者都具備讀寫權限。 |
// Allow read/write access to all users under any conditions // Warning: **NEVER** use this rule set in production; it allows // anyone to overwrite your entire database. service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if true; } } }
解決方案:限制讀寫權限的規則。 建立符合資料階層的規則。其中一項常見的做法是建立以使用者為基礎的安全防護機制,並搭配使用 Firebase 驗證功能。進一步瞭解如何使用規則驗證使用者。 |
僅限內容擁有者
service cloud.firestore { match /databases/{database}/documents { // Allow only authenticated content owners access match /some_collection/{document} { // Allow reads and deletion if the current user owns the existing document allow read, delete: if request.auth.uid == resource.data.author_uid; // Allow creation if the current user owns the new document allow create: if request.auth.uid == request.resource.data.author_uid; // Allow updates by the owner, and prevent change of ownership allow update: if request.auth.uid == request.resource.data.author_uid && request.auth.uid == resource.data.author_uid; } } }
混合使用公開和私人存取權
service cloud.firestore { match /databases/{database}/documents { // Allow public read access, but only content owners can write match /some_collection/{document} { // Allow public reads allow read: if true // Allow creation if the current user owns the new document allow create: if request.auth.uid == request.resource.data.author_uid; // Allow updates by the owner, and prevent change of ownership allow update: if request.auth.uid == request.resource.data.author_uid && request.auth.uid == resource.data.author_uid; // Allow deletion if the current user owns the existing document allow delete: if request.auth.uid == resource.data.author_uid; } } }
任何已驗證的使用者都能存取
有時,Firestore 安全性規則會檢查使用者是否已登入,但不會根據該驗證進一步限制存取權。如果其中一項規則包含 auth != null
,請確認您要允許任何已登入的使用者存取資料。
不建議:任何登入的使用者都能讀取及寫入整個資料庫。 |
service cloud.firestore { match /databases/{database}/documents { match /some_collection/{document} { allow read, write: if request.auth != null; } } }
解決方案:使用安全條件縮減存取權。 檢查驗證時,您可能也會想使用其中一個驗證屬性,進一步限制特定使用者存取特定資料集。進一步瞭解如何新增安全性條件和以角色為基礎的存取權。 |
角色型存取權
service cloud.firestore { match /databases/{database}/documents { // Assign roles to all users and refine access based on user roles match /some_collection/{document} { allow read: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader" allow write: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer" // Note: Checking for roles in your database using `get` (as in the code // above) or `exists` carry standard charges for read operations. } } }
以屬性為準的存取權
// Give each user in your database a particular attribute // and set it to true/false // Then, use that attribute to grant access to subsets of data // For example, an "admin" attribute set // to "true" grants write access to data service cloud.firestore { match /databases/{database}/documents { match /collection/{document} { allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true; allow read: true; } } }
混合使用公開和私人存取權
service cloud.firestore { match /databases/{database}/documents { // Allow public read access, but only content owners can write match /some_collection/{document} { allow read: if true allow write: if request.auth.uid == request.resource.data.author_uid } } }
未經驗證電子郵件地址的存取權
有時,Firestore 安全性規則會檢查使用者的電子郵件是否屬於特定網域。雖然這通常是不錯的做法,但使用者收到驗證電子郵件並執行額外步驟前,系統不會在登入期間驗證電子郵件。請務必驗證電子郵件地址確實屬於使用者。
不建議:任何使用者都能以任意電子郵件地址登入。 |
service cloud.firestore { match /databases/{database}/documents { // Allow access based on email domain match /some_collection/{document} { allow read: if request.auth != null && request.auth.email.endsWith('@example.com') } } }
解決方案:縮小存取範圍,僅限已驗證的電子郵件。 |
驗證電子郵件
service cloud.firestore { match /databases/{database}/documents { // Allow access based on email domain match /some_collection/{document} { allow read: if request.auth != null && request.auth.email_verified && request.auth.email.endsWith('@example.com') } } }
封閉測試
開發應用程式時,另一種常見做法是鎖定資料。通常這表示您已對所有使用者關閉讀取和寫入存取權,如下所示:
// Deny read/write access to all users under any conditions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Firebase Admin SDK 和 Cloud Functions 仍可存取資料庫。如果您打算搭配使用 Firebase Admin SDK,將 Firestore 原生模式做為僅限伺服器的後端,請使用這些規則。雖然安全無虞,但您應測試應用程式的用戶端是否能正確擷取資料。
如要進一步瞭解 Firestore 安全性規則及其運作方式,請參閱「開始使用 Firestore 安全性規則」。
檢查 Firestore 安全性規則
如要檢查應用程式的行為並驗證 Firestore 安全性規則設定,請使用 Firestore 原生模式模擬器。在部署任何變更之前,請先使用 Firestore 原生模式模擬器在本機環境中執行及自動化單元測試。
如要在 Firebase 控制台中快速測試更新後的 Firestore 安全性規則,請使用規則遊樂場工具。
- 如要開啟規則遊樂場,請按一下「規則」分頁中的「規則遊樂場」。
- 在「規則遊樂場」設定中,選取測試選項,包括:
- 測試讀取或寫入作業
- 資料庫中的特定「位置」,以路徑形式表示
- 驗證類型:未通過驗證、已通過驗證的匿名使用者,或特定使用者 ID
- 規則明確參照的文件專屬資料 (例如,規則要求必須有特定欄位,才能允許寫入)
- 按一下「執行」,然後在規則視窗上方的橫幅中查看結果。