Firebaseセキュリティルール
「Firebase」の「Firebaseセキュリティルール」についてまとめました。
1. Firebaseセキュリティルール
「Firebase」では、「Firebase セキュリティルール」を使用して、「Cloud Firestore」「Cloud Storage」のデータを保護します。ユーザーがアクセスできるデータを定義します。
2. 本番モードとテストモード
「Cloud Firestore」「Cloud Storage」ではストレージ構築時にセキュリティルールとして、「本番モード」と「テストモード」の選択を要求されます。
「本番モード」は全ユーザーアクセス不可、「テストモード」は全ユーザーアクセス可となります。
・本番モード - 全ユーザーアクセス不可
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
・テストモード - 全ユーザーアクセス可 (1ヶ月間)
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.time < timestamp.date(2023, 4, 1);
}
}
}
「Firebase Authentication」で認証したユーザーのみアクセス可にするには、次のように設定します。
・Firebase Authenticationで認証したユーザーのみアクセス可
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
本番運用では、データごとに自分のデータにしかアクセスできないようにするなど、サービスに適したルールを設定する必要があります。
3. Firebaseセキュリティルールの書式
3-1. 基本書式
「セキュリティルール言語」の基本書式は、次のとおりです。
rules_version = '2';
service <<name>> {
// リソースパスのマッチング
match <<path>> {
// 条件がtrueの場合に要求を許可
allow <<methods>> : if <<condition>>
}
}
3-2. match
「match」には、次の2種類があります。
「request.path」に「/example/hello/nested/path」を渡すと、次のように許可するかどうかを判定します。{variable} はシングルセグメントワイルドカード、{variable=**} はマルチセグメントワイルドカードとなります。
service firebase.storage {
// Partial match
match /example/{singleSegment} { // singleSegment == 'hello'
allow write; // writeを不許可
// Complete match.
match /nested/path { // singleSegment visible in scope.
allow read; // readを許可
}
}
// Complete match
match /example/{multiSegment=**} { // multiSegment == /hello/nested/path
allow read; // readを許可
}
}
3-3. allow
「allow」で許可するかどうかは、一致したすべてのルールの論理和になります。次の例では、2つ目のルールでread・deleteを許可していませんが、1つ目のルールでread・deleteを許可してるため、許可となります。
service firebase.storage {
// userディレクトリ下のデータのread・deleteを許可
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// userディレクトリ下のpngのread・delete・writeを許可
match /users/{userId}/images/{imageId} {
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
3-4. methods
「allow」に指定する「methods」は、次のとおりです。
同じmatch内でのreadやwriteのオーバーラップはエラーとなります。たとえば、次のルールはエラーとなります。
service bad.example {
match /rules/with/overlapping/methods {
// 認証済みユーザーのreadを許可
allow read: if request.auth != null;
match another/subpath {
// readのオーバーラップでエラー
allow get: if request.auth != null && request.auth.uid == "me";
// writeのオーバーラップでエラー
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
3-5. function
セキュリティルールは、カスタム関数もサポートしています。JavaScriptに似ていますが、ドメイン固有の言語で記述されており、いくつかの重要な制限があります。
service cloud.firestore {
match /databases/{database}/documents {
// 認証済みユーザーか、データが「public」である場合はtrue
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
let代入文は「;」で区切る必要があります。
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
データアクセスには遅延が発生します。以下では、isAuthorがtrueの場合のみ2番目の関数を呼び出して対策しています。
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
return isAuthor || isAdmin(userId);
}
4. Firebaseセキュリティルールの変数
4-1. request
「request」は、データアクセスのリクエストの情報を、ルールで利用するための変数です。
4-2. resource
「resource」は、データアクセスをリクエストされているデータの情報を、ルールで利用するための変数です。
キーと値のペアのマップで表されるサービス内の現在の値です。条件内でリソースを参照すると、サービスから値が最大 1 回読み取られます。このルックアップは、リソースのサービス関連のクォータにカウントされます。
4-3. auth
「auth」はデータアクセスをリクエストしているユーザーの情報を、ルールで利用するための変数です。
auth.tokenには、次の値が含まれます。
関連
この記事が気に入ったらサポートをしてみませんか?