2017-11-07 2 views
4

, 나는 단지 (사용자 정의 할당) 관리자가 자원을// 업데이트 쓰기 삭제할 수 있도록하기 위해 노력하고있어, 그리고 그것을 위해 나는이 보안 규칙이있어 :중포 기지 경우 FireStore : 중포 기지 경우 FireStore에서 사용자 정의 관리자 권한

service cloud.firestore { 
    match /databases/{database}/documents { 
    match /resources { 
     allow read; 
     allow write, update, delete: if get(/users/$(request.auth.uid).isAdmin); 
    } 
    match /resources/{resource} { 
     allow read; 
     allow write, update, delete: if get(/users/$(request.auth.uid).isAdmin); 
    } 
    } 
} 

내가 사용자의 관리자로 표시되어 사용자로 로그인하고있어 모음 :

users collection has a single admin

NfwIQAjfNdS85yDvd5yPVDyMTUj2는 UI이다 D는 인증 창에서받은 : 어떤 이유로 (들어,

The user exists

그러나 UPDATE : 이유를 식별; 답변을 참조하십시오.) PERMISSION_DENIED 자원에 콜렉션에 글을 쓸 때 실수로 관리자 권한으로 로그인 한 후 오류가 발생합니다.

아마도 Firestore에서 요청 로그를 볼 수 있습니까? 그런 다음 request.auth.uid이 내 컬렉션 및 규칙과 일치 하는지를 살펴볼 수 있습니다.

답변

4

제 질문을 쓰면서 작동했습니다! 나는 두 가지 실수를 저질렀는데, 두 가지 모두 실수로 문서를 읽으면 피할 수있었습니다.

첫째에서, service-defined functionget 요구에 대한 모든 호출은 /데이터베이스/$ (데이터베이스)/문서/과 경로를 접두사합니다. 이 규칙 있도록 :

allow write: if get(/users/$(request.auth.uid)).isAdmin; 

이된다 :

allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).isAdmin; 

그것은 긴, 난 알아,하지만 그것이 얼마나 그입니다. 파이어 스토어가 그 자체로 그 일을 할 수없는 이유는 모르겠지만 같은 경로 접두사가 모든 호출에서 동일하게 유지되는 것을 보는 것은 get이지만, 아직 준비되지 않은 일부 기능에 대한 것일 수도 있습니다. 크로스 데이터베이스 쿼리 또는 뭔가를 좋아해요. 둘째

get 기능이 차례로 당신이 포함 된 실제 데이터를 얻을 수에 .data를 호출 할 필요거야 resource을 반환합니다. 따라서, 대신이 일을 :

get(/path/to/user/).isAdmin 

이 작업을 수행해야합니다 :

:

get(/path/to/user/).data.isAdmin 

지금 난 그냥 내가 user-defined function에 그 논리를 추출 할 수 있었으면 좋겠어

function isAdmin() { 
    return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin; 
} 

이렇게하면 PERMISSION_DENIED가 다시이됩니다. 함수에서 실제로 무슨 일이 벌어지고 있는지를 알지 못한다면, 지금 이것을 알아 내려고 노력하는 데 더 많은 시간을 할애 할 것인지 확신 할 수 없습니다.

UPDATE : @Hareesh pointed out 함수는 정규의 범위 내에서 정의해야합니다, 그래서 다음과 같은 기본 최상위 정규의 기능을 넣을 수 있다는 :

service cloud.firestore { 
    match /databases/{database}/documents { 
    function isAdmin() { 
     return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true; 
    } 

    // ... 
    } 
} 
2

일부 지점 전 공지 된

는 해당 문서에 아무런 영향을 미치지 않는 컬렉션을 가리키고 있습니다. 여기에서 나는 인용하고있다. doc

수집 규칙은 해당 컬렉션 내의 문서에는 적용되지 않습니다. 문서 수준이 아닌 컬렉션 수준에서 작성된 보안 규칙을 사용하는 것은 드문 경우입니다 (그리고 아마도 오류).

그래서 당신은 그런 규칙에 당신도 allow write: 또는 특별히 allow create, update, delete: 세 가지 옵션 중 하나를 말하거나 결합 할 수 있습니다 allow write, update, delete: 컬렉션

규칙을 작성할 필요가 없습니다.

service cloud.firestore { 
    match /databases/{database}/documents { 
     match /resources/{resource} { 

     function isAdmin() { 
      return get(/databases/$(database)/documents/users/$(request.auth.uid)).isAdmin || 
      get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin; 
     } 

     allow read; 
     allow create, update, delete: if isAdmin(); 
    } 
    } 
} 
+0

오 시도, 좋은! 나는 수집 수준에 관한 규칙에 관한 부분을 주목하지 못했다. 감사! 또한 이전에 실제로'create, update, delete '를 했었고, 이제는 다른 것들을 실험하기 위해 실험 해 보았습니다.하지만 당신이 맞습니다. 그것은'write' 일뿐입니다. matchers 내부에 함수를 넣으려고 시도하지만, 내 생각에 그 종류의 목적을 무력화. :-) – sindrenm

+0

예 [여기] (https://firebase.google.com/docs/firestore/security/secure-data#writing_custom_functions)와 같은 여러 유효성 검사를 위해서만 함수를 사용합니다. – Hareesh

+0

그래서 최상위 레벨 정규 표현식에 함수를 넣습니다. (/ 데이터베이스/{데이터베이스}/문서) 잘 작동합니다! 그렇다면 문제는 없습니다. 고마워, @Hareesh, 내 대답을 업데이 트하겠습니다. :-) – sindrenm

관련 문제