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.uid
request.auth.token.email
request.resource.data.score
: Firestore에서 제공하는 resource로 다음과 같은 속성을 가지고 있다.
resource.data.reviewerId
resource.data.reviewerId === request.auth.uid
Path는 중첩이 가능하다.
/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보다 이전이라면 읽기와 쓰기를 허용한다.
}
}
}
파이어베이스.... ㅠ 잘 보고 갑니당