Firebase セキュリティ ルールを使用すると、保存されているデータへのアクセスを制御できます。柔軟なルール構文は、データベース全体へのすべての書き込みから特定のドキュメントの操作まで、あらゆるものに一致するルールを作成できることを意味します。
このガイドでは、アプリをセットアップしてデータを保護する際に実装できる、より基本的なユース ケースのいくつかについて説明します。ただし、ルールの記述を開始する前に、ルールが記述されている言語とその動作について詳しく学習することをお勧めします。
ルールにアクセスして更新するには、 Firebase セキュリティ ルールの管理とデプロイで説明されている手順に従います。
デフォルトのルール: ロック モード
Firebase コンソールでデータベースまたはストレージ インスタンスを作成するときに、Firebase セキュリティ ルールでデータへのアクセスを制限するか (ロック モード)、誰でもアクセスできるようにするか (テスト モード) を選択します。 Cloud Firestore と Realtime Database では、ロック モードのデフォルト ルールにより、すべてのユーザーへのアクセスが拒否されます。 Cloud Storage では、認証されたユーザーのみがストレージ バケットにアクセスできます。
クラウド ファイアストア
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
リアルタイム データベース
{
"rules": {
".read": false,
".write": false
}
}
クラウドストレージ
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
開発環境ルール
アプリに取り組んでいる間、データへの比較的オープンな、または自由なアクセスが必要になる場合があります。アプリを本番環境にデプロイする前に、必ずルールを更新してください。また、アプリをデプロイすると、アプリを起動していなくても、パブリックにアクセスできることを忘れないでください。
Firebase では、クライアントがデータに直接アクセスできます。Firebase セキュリティ ルールは、悪意のあるユーザーのアクセスをブロックする唯一の保護手段です。製品のロジックとは別にルールを定義することには、多くの利点があります。クライアントはセキュリティを実施する責任がなく、バグのある実装によってデータが危険にさらされることはありません。また、最も重要なことは、データを外部から保護するために中間サーバーに依存する必要がないことです。
すべての認証済みユーザー
サインインしているすべてのユーザーがデータにアクセスできるようにすることはお勧めしませんが、アプリの開発中に認証済みユーザーにアクセス権を設定すると便利な場合があります。
クラウド ファイアストア
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
リアルタイム データベース
{
"rules": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
クラウドストレージ
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
本番対応のルール
アプリをデプロイする準備をするときは、データが保護されていること、およびアクセスがユーザーに適切に付与されていることを確認してください。認証を利用してユーザーベースのアクセスを設定し、データベースから直接読み取り、データベースのアクセスを設定します。
ルールを設定する方法は、さまざまなパスでデータへのアクセスを制限する方法に影響するため、データを構造化するときにルールを記述することを検討してください。
コンテンツ所有者のみのアクセス
これらのルールは、コンテンツの認証された所有者のみへのアクセスを制限します。データは 1 人のユーザーのみが読み書きでき、データ パスにはユーザーの ID が含まれます。
このルールが機能する場合:このルールは、データがユーザーごとにサイロ化されている場合 (データにアクセスする必要がある唯一のユーザーがデータを作成したユーザーと同じ場合) にうまく機能します。
このルールが機能しない場合:複数のユーザーが同じデータを読み書きする必要がある場合、このルールセットは機能しません。ユーザーはデータを上書きするか、作成したデータにアクセスできなくなります。
このルールを設定するには:データの読み取りまたは書き込みアクセスを要求しているユーザーが、そのデータを所有するユーザーであることを確認するルールを作成します。
クラウド ファイアストア
service cloud.firestore {
match /databases/{database}/documents {
// Allow only authenticated content owners access
match /some_collection/{userId}/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == userId
}
}
}
リアルタイム データベース
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
}
クラウドストレージ
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
パブリック アクセスとプライベート アクセスの混合
このルールでは、誰でもデータ セットを読み取ることができますが、特定のパスでデータを作成または変更する機能は、認証されたコンテンツ所有者のみに制限されます。
このルールが機能する場合:このルールは、パブリックに読み取り可能な要素を必要とするが、それらの要素の所有者に編集アクセスを制限する必要があるアプリに適しています。たとえば、チャット アプリやブログです。
このルールが機能しない場合:コンテンツ所有者のみのルールと同様に、複数のユーザーが同じデータを編集する必要がある場合、このルールセットは機能しません。ユーザーは最終的に互いのデータを上書きします。
このルールを設定するには:すべてのユーザー (またはすべての認証済みユーザー) の読み取りアクセスを有効にし、データを書き込んでいるユーザーが所有者であることを確認するルールを作成します。
クラウド ファイアストア
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 create: if request.auth.uid == request.resource.data.author_uid;
allow update, delete: if request.auth.uid == resource.data.author_uid;
}
}
}
リアルタイム データベース
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path": {
"$uid": {
".read": true,
// or ".read": "auth.uid !== null" for only authenticated users
".write": "auth.uid === $uid"
}
}
}
}
クラウドストレージ
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
属性ベースおよび役割ベースのアクセス
これらのルールを機能させるには、データ内で属性を定義してユーザーに割り当てる必要があります。 Firebase セキュリティ ルールは、データベースまたはファイルのメタデータからのデータに対してリクエストをチェックして、アクセスを確認または拒否します。
このルールが機能する場合:ユーザーにロールを割り当てる場合、このルールにより、ロールまたは特定のユーザー グループに基づいてアクセスを簡単に制限できます。たとえば、成績を保存している場合、「学生」グループ (コンテンツの読み取りのみ)、「教師」グループ (科目の読み取りと書き込み)、および「校長」グループ (読み取り) に異なるアクセス レベルを割り当てることができます。すべてのコンテンツ)。
このルールが機能しない場合: Realtime Database と Cloud Storage では、Cloud Firestore ルールに組み込むことができるget()
メソッドをルールで利用できません。したがって、ルールで使用している属性を反映するように、データベースまたはファイルのメタデータを構造化する必要があります。
このルールを設定するには: Cloud Firestore で、読み取り可能なユーザーのドキュメントにフィールドを含め、そのフィールドを読み取り、条件付きでアクセスを許可するようにルールを構成します。 Realtime Database で、アプリのユーザーを定義するデータ パスを作成し、子ノードでロールを付与します。
Authentication でカスタム クレームを設定し、Firebase セキュリティ ルールのauth.token
変数からその情報を取得することもできます。
データ定義の属性と役割
これらのルールは、Cloud Firestore と Realtime Database でのみ機能します。
クラウド ファイアストア
以下のルールのように、ルールに読み取りが含まれる場合は常に、Cloud Firestore での読み取り操作に対して課金されることに注意してください。
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, Check a boolean `admin` attribute
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
}
}
}
リアルタイム データベース
{
"rules": {
"some_path": {
"${subpath}": {
//
".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
".read": true
}
}
}
}
カスタム クレームの属性とロール
これらのルールを実装するには、Firebase Authentication でカスタム クレームを設定し、ルールでクレームを活用します。
クラウド ファイアストア
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, check for an admin claim
allow write: if request.auth.token.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if request.auth.token.reader == "true";
allow write: if request.auth.token.writer == "true";
}
}
}
リアルタイム データベース
{
"rules": {
"some_path": {
"$uid": {
// Create a custom claim for each role or group
// you want to leverage
".write": "auth.uid !== null && auth.token.writer === true",
".read": "auth.uid !== null && auth.token.reader === true"
}
}
}
}
クラウドストレージ
service firebase.storage {
// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
allow read: if resource.metadata.owner == request.auth.token.groupId;
allow write: if request.auth.token.groupId == groupId;
}
}
テナント属性
これらのルールを実装するには、Google Cloud Identity Platform ( GCIP ) でマルチテナンシーを設定してから、ルールでテナントを活用します。次の例では、 tenant2-m6tyz
などの特定のテナントのユーザーからの書き込みを許可します。
クラウド ファイアストア
service cloud.firestore {
match /databases/{database}/documents {
// For tenant-based access control, check for a tenantID
allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
allow read: true;
}
}
リアルタイム データベース
{
"rules": {
"some_path": {
"$uid": {
// Only allow reads and writes if user belongs to a specific tenant
".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
".read": "auth.uid !== null
}
}
}
}
クラウドストレージ
service firebase.storage {
// Only allow reads and writes if user belongs to a specific tenant
match /files/{tenantId}/{fileName} {
allow read: if request.auth != null;
allow write: if request.auth.token.firebase.tenant == tenantId;
}
}