Firestore의 보안 규칙은 커스텀 언어를 활용하는데, CEL(Common Expression Language) 기반 언어를 사용하며, match와 allow 문을 사용하여 조건부로 액세스 권한을 부여할 수 있다.
service [서비스] {
match [경로] {
allow [메소드] : if [조건]
}
}
e.g.
rules_version = '2'; // Firebase 규칙 언어의 버전을 나타낸다. 최신 언어 버전은 v2이며, rules_version문이 제공되지 않으면 규칙이 v1 엔진을 사용하여 평가된다.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read;
allow write: if request.auth != null;
}
}
}
service 선언은 규칙이 적용되는 Firebase 제품 또는 서비스를 정의한다.서비스에는 하나 이상의 match 블록과 allow문이 포함된다.service 선언만 포함할 수 있다.service cloud.firestore {
// ...
}
match의 본문에는 하나 이상의 중첩된 match 블록, allow문, 또는 function 선언이 있어야 한다.path와 부분적으로 일치하거나 완전하게 일치할 수 있다.: path가 request.path의 prefix(앞부분)와 일치하는 경우
e.g. request.path가 /example/hello/nested/path일 때,
service cloud.firestore {
match /example/{singleSegment} { // singleSegment == 'hello'
allow write;
}
}
: path가 request.path와 완전히 일치하는 경우
e.g. request.path가 /example/hello/nested/path일 때,
service cloud.firestore {
match /example/{singleSegment} { // singleSegment == 'hello'
allow write;
match /nested/path { // 완전 일치
allow read;
}
}
// 완전 일치
match /example/{multiSegment=**} { // mutlSegment == 'hello/nested/path'
allow read;
}
}
path는 변수 또는 와일드 카드를 포함할 수 있다.path는 단일 경로 세그먼트와 다중 경로 세그먼트 일치를 허용한다.: 와일드 카드 변수는 중괄호 {}로 래핑하여 경로에 선언할 수 있다.
match /example/{singleSegment} {...}
: 다중/재귀적 와일드 카드는 설정한 경로 아래의 모든 경로와 일치한다. 세그먼트 변수 끝에 =** 문자열을 추가하여 선언할 수 있다.
match /example/{multiSegment=**} {...}
Wildcard
컬렉션 안의 도큐멘트만 선택
match /todos/{todoId} {} // todos 컬렉션 안에 있는 도큐멘트만 선택한다. (하위 컬렉션 안의 도큐멘트는 제외)하위 컬렉션까지 선택
match /todos/{restOfPath=**} {} // todos 컬렉션의 모든 도큐멘트 뿐만 아니라 todo 컬렉션 안에 있는 모든 하위 컬렉션의 도큐먼트까지 선택한다.match /databases/{database}/documents { // Firestore 데이터베이스의 match /{document=**} { // 모든 도큐먼트에 (하위 도큐먼트 포함) allow read, write: if // 읽기와 쓰기를 허용한다. request.time < timestamp.date(2021, 2, 27); // 요청의 시간이 2021.2.27보다 이전이라면 } }
read, write 또는 get, list, create, update, delete를 사용할 수 있다.allow문에 조건이 포함되어있지 않으면 메소드의 요청이 항상 허용된다.request 및 resources 변수를 사용할 수 있다.service firebase.storage {
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth !== null && request.auth.uid == userId;
// request에 auth가 존재하고, uid가 userId랑 일치할 때만 읽기와 삭제를 허용한다.
}
: 클라이언트로부터 받아온 resource로 다음과 같은 속성을 가지고 있다.
request.auth.uidrequest.auth.token.emailrequest.resource.data.score: Firestore에서 제공하는 resource로 다음과 같은 속성을 가지고 있다.
resource.data.reviewerIdresource.data.reviewerId === request.auth.uidPath는 중첩이 가능하다.
/database/{database}/documents/users/{userId}
// users 컬렉션 안의 user 도큐먼트
/database/{database}/documents/todos/{todoId}
// todos 컬렉션 안의 todo 도큐먼트
/database/{database}/documents/todos/{userId}/userTodos/{todoId}
// todos 컬렉션 안의 user 도큐먼트 안의 userTodos 하위 컬렉션 안의 todo 도큐먼트
match /databases/{database}/documents {
match /restaurants/{restaurantId} { // restaurants 컬렉션 안의 restaurant 도큐먼트 안의
match /reviews/{reviewId} { // reviews 하위 컬렉션의 reviewsId 도큐먼트에
allow write: if request.time < timestamp.date(2021, 2, 27); // 요청의 시간이 2021.2.27보다 이전이라면 읽기와 쓰기를 허용한다.
}
}
}
파이어베이스.... ㅠ 잘 보고 갑니당