Firebase 보안 규칙

지은·2023년 5월 5일
0

Firestore의 보안 규칙은 커스텀 언어를 활용하는데, CEL(Common Expression Language) 기반 언어를 사용하며, matchallow 문을 사용하여 조건부로 액세스 권한을 부여할 수 있다.

보안 규칙 언어 - Firebase

기본 구조

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;
    }
  }
}

규칙 구성

1. 서비스

  • service 선언은 규칙이 적용되는 Firebase 제품 또는 서비스를 정의한다.
  • 서비스에는 하나 이상의 match 블록과 allow문이 포함된다.
  • 소스 파일당 하나의 service 선언만 포함할 수 있다.
service cloud.firestore {
	// ...
}

2. match 블록

  • 규칙이 적용될 데이터베이스 또는 스토리지 버킷의 경로를 정의한다.
  • match의 본문에는 하나 이상의 중첩된 match 블록, allow문, 또는 function 선언이 있어야 한다.
  • path와 부분적으로 일치하거나 완전하게 일치할 수 있다.

부분 일치

: pathrequest.path의 prefix(앞부분)와 일치하는 경우

e.g. request.path가 /example/hello/nested/path일 때,

service cloud.firestore {
	match /example/{singleSegment} { // singleSegment == 'hello'
      allow write;
    }
}

완전 일치

: pathrequest.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보다 이전이라면
    }
}

3. allow문

  • 메소드별로 구분한 액세스 권한을 부여하도록 조건을 제공한다.
  • 메서드는 간편하게 read, write 또는 get, list, create, update, delete를 사용할 수 있다.
  • allow문에 조건이 포함되어있지 않으면 메소드의 요청이 항상 허용된다.
  • 규칙 조건 안에서 requestresources 변수를 사용할 수 있다.
service firebase.storage {
	match /users/{userId}/{anyUserFile=**} {
    	allow read, delete: if request.auth !== null && request.auth.uid == userId;
        // request에 auth가 존재하고, uid가 userId랑 일치할 때만 읽기와 삭제를 허용한다.
    }

request 객체

: 클라이언트로부터 받아온 resource로 다음과 같은 속성을 가지고 있다.

  • auth : Firebase 인증의 사용자 인증 정보를 포함하고 있는 JSON 웹 토큰(JWT)
    • uid ➡️ request.auth.uid
    • token ➡️ request.auth.token.email
  • resource
    • data ➡️ request.resource.data.score

resource 객체

: Firestore에서 제공하는 resource로 다음과 같은 속성을 가지고 있다.

  • resource
    • data ➡️ resource.data.reviewerId
      e.g. resource.data.reviewerId === request.auth.uid

Path

Path는 중첩이 가능하다.

Full 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 도큐먼트

Nested path

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보다 이전이라면 읽기와 쓰기를 허용한다.
    }
  }
}
profile
개발 공부 기록 블로그

4개의 댓글

comment-user-thumbnail
2023년 5월 6일

파이어베이스.... ㅠ 잘 보고 갑니당

답글 달기
comment-user-thumbnail
2023년 5월 7일

firebase 사용해서 하시는군요!

답글 달기
comment-user-thumbnail
2023년 5월 7일

그나마 쉬운게 파이어베이스라던데, 왜 이해가 잘 안되죠? ㅋㅋㅋㅋ

답글 달기
comment-user-thumbnail
2023년 5월 7일

한번도 써보지 못한 저로서는 어렵네요,, Next랑 같이 쓰면 좋을라나

답글 달기