-
SWeetMe Project - FireStore 보안 규칙프로젝트 2024. 3. 18. 22:07반응형
파이어스토어 기능을 추가할 때 테스트 모드로 시작하면 한 달 정도 읽기, 쓰기가 가능하도록 보안 규칙이 자동 설정이 된다.
개발할 때는 당장 신경쓸 필요가 없지만, 따로 보안 규칙을 설정하지 않으면 데이터베이스가 보호되지 않기 때문에 보안 규칙 적용이 꼭 필요하다.
보안 규칙을 수정하면서 공부했던 내용을 정리해보았다.
FireStore의 보안 규칙은 커스텀 언어를 활용한다. CEL(Common Expression Language) 기반 언어이며, match와 allow를 사용해 조건부 액세스 권한을 부여한다. - 보안 규칙 언어
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.time < timestamp.date(2024, 1, 6); } }
위 코드는 테스트 모드로 시작했을 때 자동 설정된 보안 규칙이다. (2024.01.05까지만 허용)
1. 보안 규칙 버전
rules_version = '2';
2019년 5월부터 규칙 버전 2를 사용할 수 있게 되었다고 한다. 기존 버전 1은 와일드 카드(ex) document=**)를 사용할 때 1개 이상의 path를 포함해야 했고, zero path(빈 경로)를 허용하는 규칙 버전 2가 출시되었다.
2. 기본 구조
service [서비스 e.g) cloud.firestore] { match [경로 e.g) /databases/{database}/documents] { allow [함수(read, write ... )] : if <조건>; } }
2-1. service block
service block에서는 규칙을 적용할 서비스를 명시해준다.
하나 이상의 match, allow block이 포함되어야 하며, 소스 파일당 하나의 service 선언만 포함할 수 있다.
2-2. match block
match block에서는 프로젝트의 모든 데이터 베이스를 포함시키는 구문이 자동으로 들어가있는데, 규칙이 적용될 데이터 베이스 또는 storage bucket 경로를 지정할 수 있다.
match block 내부에는 하나 이상의 중첩된 match block, allow, function 선언이 있어야 한다.
match /test/test1 { allow read, write: if true; } match /test/{testSample} { allow read, write: if true; } match /test/{testSample=**} { allow read, write: if true; }
위에서부터 순서대로
1. test collection 하위의 test1 문서에 대해 읽기, 쓰기 허용
2. test collection 하위의 document에 대한 읽기 쓰기 허용(sub collection 내부 document 제외)
3. test collection 하위의 모든 document에 대한 읽기 쓰기 허용
2-3. allow block
메소드 별로 액세스 권한을 부여하도록 조건을 제공한다.
read 또는 get, list / write 또는 create, update, delete로 구분해서 사용할 수 있다.
조건 block에서는 request, resource 변수를 사용할 수 있다.
1. request -> 클라이언트로부터 받아온 객체. auth와 resource 속성 등을 가지고 있다. - 객체에 대한 자세한 설명
request.auth -> 사용자 인증 정보 포함하는 JSON 웹 토큰(JWT) request.method -> get, list, create, update, delete 중 하나 request.path -> 경로 request.query -> 쿼리 속성(limit, offset, orderBy 중 존재하는 것) request.resource.data -> 사용자가 보낸 데이터, write method 내에서만 사용 가능 (추가적인 보안 규칙 설정 가능) request.time -> 요청 시간
2. resource -> FireStore에서 제공하는 객체. data 속성을 가지고 있다 - 객체에 대한 자세한 설명
resource.id -> document id resource.data -> document의 모든 필드 값 참조 가능
3. 다른 문서 액세스
보안 규칙에서 get() 및 exists() 함수를 사용하여 수신된 요청을 데이터 베이스의 다른 문서와 비교할 수 있다.
변수를 사용하여 path를 작성하는 경우 $(변수) 구문을 사용하여 변수를 명시적으로 이스케이프 해야한다.
get()은 지정 문서 이외의 다른 문서를 가져와서 비교할 때, exists()는 다른 문서의 데이터 존재 여부를 알기 위해서 사용한다.
// test collection의 test1 문서의 field1의 값이 true인 경우 if get(/databases/$(database)/documents/test/$(test1)).data.field1 == true // test collection의 test1 문서가 존재할 경우 if exists(/databases/$(database)/documents/test/$(test1))
4. 함수 사용
반복적으로 사용하는 규칙의 경우 함수로 만들 수 있다.
function checkLoggedIn() { return request.auth.uid != null; }
주의 해야할 점
보안 규칙은 필터가 아니다. 따라서 파이어베이스 앱 내의 쿼리와 보안 규칙 모두 일치되는 쿼리를 사용해야한다.
match ~/test/{testSample} { allow read: if request.auth.token.email == resource.data.uid; } Firestore.instance.collection('test').where('uid', isEqualTo: test@naver.com).getDocuments();
위 예시처럼 보안 규칙 쿼리와 파이어베이스 앱 내의 쿼리가 일치한다.
보안 규칙에만 쿼리를 적용하는 경우, 파이어베이스 앱 내에서 읽기, 쓰기 요청을 보냈을 때 해당 요청을 거부할 수 있다.
반응형'프로젝트' 카테고리의 다른 글
Flask Project - MyBlog Flask-sqlalchemy(with Flask-migrate) DB 관리 (0) 2024.04.08 Flask Project - MyBlog 프로젝트 목적, 아키텍쳐, Config, gitignore 관리 (2) 2024.04.08 SWeetMe Project - 회원가입, 로그인 기능 (1) 2024.03.18 감정 일기장 프로젝트 소개 (1) 2024.03.18 SWeetMe 프로젝트 소개 (2) 2024.03.18