Xác thực dữ liệu

Bạn có thể sử dụng Quy tắc bảo mật Firebase để ghi dữ liệu mới có điều kiện dựa trên dữ liệu hiện có trong cơ sở dữ liệu hoặc nhóm lưu trữ của bạn. Bạn cũng có thể viết các quy tắc thực thi xác thực dữ liệu bằng cách hạn chế ghi dựa trên dữ liệu mới được ghi. Đọc tiếp để tìm hiểu thêm về các quy tắc sử dụng dữ liệu hiện có để tạo điều kiện bảo mật.

Chọn một sản phẩm trong mỗi phần để tìm hiểu thêm về quy tắc xác thực dữ liệu.

Hạn chế về dữ liệu mới

Cửa hàng đám mây

Nếu bạn muốn đảm bảo rằng tài liệu chứa một trường cụ thể không được tạo, bạn có thể đưa trường đó vào điều kiện allow . Ví dụ: nếu bạn muốn từ chối việc tạo bất kỳ tài liệu nào có chứa trường ranking , bạn sẽ không cho phép điều đó trong điều kiện create .

  service cloud.firestore {
    match /databases/{database}/documents {
      // Disallow
      match /cities/{city} {
        allow create: if !("ranking" in request.resource.data)
      }
    }
  }

Cơ sở dữ liệu thời gian thực

Nếu bạn muốn đảm bảo rằng dữ liệu chứa các giá trị nhất định không được thêm vào cơ sở dữ liệu của mình, bạn nên đưa giá trị đó vào quy tắc của mình và không cho phép ghi. Ví dụ: nếu bạn muốn từ chối bất kỳ thao tác ghi nào có chứa giá trị ranking , bạn sẽ không cho phép ghi đối với bất kỳ tài liệu nào có giá trị ranking .

  {
    "rules": {
      // Write is allowed for all paths
      ".write": true,
      // Allows writes only if new data doesn't include a `ranking` child value
      ".validate": "!newData.hasChild('ranking')
    }
  }

Lưu trữ đám mây

Nếu bạn muốn đảm bảo rằng tệp chứa siêu dữ liệu cụ thể không được tạo, bạn có thể đưa siêu dữ liệu vào điều kiện allow . Ví dụ: nếu bạn muốn từ chối việc tạo bất kỳ tệp nào chứa siêu dữ liệu ranking , bạn sẽ không cho phép nó trong điều kiện create .

  service firebase.storage {
    match /b/{bucket}/o {
      match /files/{allFiles=**} {
      // Disallow
        allow create: if !("ranking" in request.resource.metadata)
      }
    }
  }

Sử dụng dữ liệu hiện có trong Quy tắc bảo mật của Firebase

Cửa hàng đám mây

Nhiều ứng dụng lưu trữ thông tin kiểm soát quyền truy cập dưới dạng các trường trên tài liệu trong cơ sở dữ liệu. Quy tắc bảo mật của Cloud Firestore có thể tự động cho phép hoặc từ chối quyền truy cập dựa trên dữ liệu tài liệu:

  service cloud.firestore {
    match /databases/{database}/documents {
      // Allow the user to read data if the document has the 'visibility'
      // field set to 'public'
      match /cities/{city} {
        allow read: if resource.data.visibility == 'public';
      }
    }
  }

Biến resource đề cập đến tài liệu được yêu cầu và resource.data là bản đồ của tất cả các trường và giá trị được lưu trữ trong tài liệu. Để biết thêm thông tin về biến resource , hãy xem tài liệu tham khảo .

Khi ghi dữ liệu, bạn có thể muốn so sánh dữ liệu đến với dữ liệu hiện có. Điều này cho phép bạn thực hiện những việc như đảm bảo trường không thay đổi, trường chỉ tăng thêm một hoặc giá trị mới có ít nhất một tuần trong tương lai. Trong trường hợp này, nếu bộ quy tắc của bạn cho phép ghi đang chờ xử lý, biến request.resource sẽ chứa trạng thái tương lai của tài liệu. Đối với các thao tác update chỉ sửa đổi một tập hợp con của các trường tài liệu, biến request.resource sẽ chứa trạng thái tài liệu đang chờ xử lý sau thao tác. Bạn có thể kiểm tra các giá trị trường trong request.resource để ngăn các cập nhật dữ liệu không mong muốn hoặc không nhất quán:

   service cloud.firestore {
     match /databases/{database}/documents {
      // Make sure all cities have a positive population and
      // the name is not changed
      match /cities/{city} {
        allow update: if request.resource.data.population > 0
                      && request.resource.data.name == resource.data.name;
      }
    }
  }

Cơ sở dữ liệu thời gian thực

Trong Cơ sở dữ liệu thời gian thực, sử dụng quy tắc .validate để thực thi cấu trúc dữ liệu và xác thực định dạng cũng như nội dung của dữ liệu. Quy tắc chạy quy tắc .validate sau khi xác minh rằng quy tắc .write cấp quyền truy cập.

Các quy tắc .validate không xếp tầng. Nếu bất kỳ quy tắc xác thực nào không thành công trên bất kỳ đường dẫn hoặc đường dẫn phụ nào trong quy tắc thì toàn bộ thao tác ghi sẽ bị từ chối. Ngoài ra, các định nghĩa xác thực chỉ kiểm tra các giá trị khác null và sau đó bỏ qua mọi yêu cầu xóa dữ liệu.

Hãy xem xét các quy tắc .validate sau:

  {
    "rules": {
      // write is allowed for all paths
      ".write": true,
      "widget": {
        // a valid widget must have attributes "color" and "size"
        // allows deleting widgets (since .validate is not applied to delete rules)
        ".validate": "newData.hasChildren(['color', 'size'])",
        "size": {
          // the value of "size" must be a number between 0 and 99
          ".validate": "newData.isNumber() &&
                        newData.val() >= 0 &&
                        newData.val() <= 99"
        },
        "color": {
          // the value of "color" must exist as a key in our mythical
          // /valid_colors/ index
          ".validate": "root.child('valid_colors/' + newData.val()).exists()"
        }
      }
    }
  }

Viết yêu cầu vào cơ sở dữ liệu với các quy tắc trên sẽ có kết quả như sau:

JavaScript
var ref = db.ref("/widget");

// PERMISSION_DENIED: does not have children color and size
ref.set('foo');

// PERMISSION DENIED: does not have child color
ref.set({size: 22});

// PERMISSION_DENIED: size is not a number
ref.set({ size: 'foo', color: 'red' });

// SUCCESS (assuming 'blue' appears in our colors list)
ref.set({ size: 21, color: 'blue'});

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
ref.child('size').set(99);
Mục tiêu-C
Lưu ý: Sản phẩm Firebase này không có sẵn trên mục tiêu App Clip.
FIRDatabaseReference *ref = [[[FIRDatabase database] reference] child: @"widget"];

// PERMISSION_DENIED: does not have children color and size
[ref setValue: @"foo"];

// PERMISSION DENIED: does not have child color
[ref setValue: @{ @"size": @"foo" }];

// PERMISSION_DENIED: size is not a number
[ref setValue: @{ @"size": @"foo", @"color": @"red" }];

// SUCCESS (assuming 'blue' appears in our colors list)
[ref setValue: @{ @"size": @21, @"color": @"blue" }];

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
[[ref child:@"size"] setValue: @99];
Nhanh
Lưu ý: Sản phẩm Firebase này không có sẵn trên mục tiêu App Clip.
var ref = FIRDatabase.database().reference().child("widget")

// PERMISSION_DENIED: does not have children color and size
ref.setValue("foo")

// PERMISSION DENIED: does not have child color
ref.setValue(["size": "foo"])

// PERMISSION_DENIED: size is not a number
ref.setValue(["size": "foo", "color": "red"])

// SUCCESS (assuming 'blue' appears in our colors list)
ref.setValue(["size": 21, "color": "blue"])

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
ref.child("size").setValue(99);
Java
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("widget");

// PERMISSION_DENIED: does not have children color and size
ref.setValue("foo");

// PERMISSION DENIED: does not have child color
ref.child("size").setValue(22);

// PERMISSION_DENIED: size is not a number
Map<String,Object> map = new HashMap<String, Object>();
map.put("size","foo");
map.put("color","red");
ref.setValue(map);

// SUCCESS (assuming 'blue' appears in our colors list)
map = new HashMap<String, Object>();
map.put("size", 21);
map.put("color","blue");
ref.setValue(map);

// If the record already exists and has a color, this will
// succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
// will fail to validate
ref.child("size").setValue(99);
NGHỈ NGƠI
# PERMISSION_DENIED: does not have children color and size
curl -X PUT -d 'foo' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# PERMISSION DENIED: does not have child color
curl -X PUT -d '{"size": 22}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# PERMISSION_DENIED: size is not a number
curl -X PUT -d '{"size": "foo", "color": "red"}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# SUCCESS (assuming 'blue' appears in our colors list)
curl -X PUT -d '{"size": 21, "color": "blue"}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json

# If the record already exists and has a color, this will
# succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
# will fail to validate
curl -X PUT -d '99' \
https://docs-examples.firebaseio.com/rest/securing-data/example/size.json

Lưu trữ đám mây

Khi đánh giá các quy tắc, bạn cũng có thể muốn đánh giá siêu dữ liệu của tệp đang được tải lên, tải xuống, sửa đổi hoặc xóa. Điều này cho phép bạn tạo các quy tắc phức tạp và mạnh mẽ để thực hiện những việc như chỉ cho phép tải lên các tệp có loại nội dung nhất định hoặc chỉ xóa các tệp lớn hơn một kích thước nhất định.

Đối tượng resource chứa các cặp khóa/giá trị với siêu dữ liệu tệp hiển thị trong đối tượng Cloud Storage. Các thuộc tính này có thể được kiểm tra theo yêu cầu read hoặc write để đảm bảo tính toàn vẹn dữ liệu. Đối tượng resource nguyên kiểm tra siêu dữ liệu trên các tệp hiện có trong nhóm Lưu trữ đám mây của bạn.

  service firebase.storage {
    match /b/{bucket}/o {
      match /images {
        match /{allImages=**} {
          // Allow reads if a custom 'visibility' field is set to 'public'
          allow read: if resource.metadata.visibility == 'public';
        }
      }
    }
  }

Bạn cũng có thể sử dụng đối tượng request.resource cho các yêu cầu write (chẳng hạn như tải lên, cập nhật siêu dữ liệu và xóa. Đối tượng request.resource lấy siêu dữ liệu từ tệp sẽ được ghi nếu write được cho phép.

Bạn có thể sử dụng hai giá trị này để ngăn các cập nhật không mong muốn hoặc không nhất quán hoặc để thực thi các ràng buộc ứng dụng, chẳng hạn như loại hoặc kích thước tệp.

  service firebase.storage {
    match /b/{bucket}/o {
      match /images {
        // Cascade read to any image type at any path
        match /{allImages=**} {
          allow read;
        }

        // Allow write files to the path "images/*", subject to the constraints:
        // 1) File is less than 5MB
        // 2) Content type is an image
        // 3) Uploaded content type matches existing content type
        // 4) File name (stored in imageId wildcard variable) is less than 32 characters
        match /{imageId} {
          allow write: if request.resource.size < 5 * 1024 * 1024
                       && request.resource.contentType.matches('image/.*')
                       && request.resource.contentType == resource.contentType
                       && imageId.size() < 32
        }
      }
    }
  }

Danh sách đầy đủ các thuộc tính trong đối tượng resource có sẵn trong tài liệu tham khảo .