Device Sync 권한 가이드
이 페이지의 내용
이 페이지에서는 다음과 같은 일반적인 사용 사례에 대해 Device Sync 앱의 권한을 설정하는 방법을 보여줍니다.
템플릿 앱 사용
이러한 Device Sync 권한 모델 중 일부는 Atlas Device Sync 앱을 사용하여 빠르게 설정하고 실행할 수 있습니다. 각 템플릿 앱은 백엔드 및 Node.js 데모 클라이언트와 함께 제공됩니다. 백엔드에는 여기에 설명된 대로 모든 기능, 권한 및 트리거를 설정할 수 있습니다. 데모 클라이언트는 백엔드에 연결하고 간단한 스크립트를 실행하여 백엔드가 어떻게 작동하는지 보여줍니다.
이러한 템플릿을 사용하려면 인증된 App Services CLI가 필요합니다.
App Services CLI는 npm
에서 사용할 수 있습니다. 시스템에 CLI를 설치하려면 Node.js 가 있어야 합니다. 설치한 다음 shell 에서 다음 명령을 실행합니다.
npm install -g atlas-app-services-cli
로그인 지침은 CLI 참조 페이지를 참조하세요.
로그인한 후에는 --template
플래그와 함께 apps create
명령을 사용하여 템플릿을 인스턴스화할 수 있습니다.
appservices apps create --template=TEMPLATE_NAME
TEMPLATE_NAME
다음 중 하나일 수 있습니다.
flex-sync-guides.add-collaborators
( 동적 협업에 해당)flex-sync-guides.restricted-feed
( 제한된 뉴스 피드에 해당)flex-sync-guides.tiered
( 계층화된 권한에 해당)
이 예제들에 대하여
여기의 예에서는 기본 역할을 사용합니다. 이는 앱의 모든 컬렉션에 동일한 권한 규칙이 적용된다는 것을 의미합니다. 앱이 복잡해지면 일부 컬렉션에만 적용되고 다른 컬렉션에는 적용되지 않는 컬렉션별 역할이 필요할 수 있습니다. 특히 기본 역할의 규칙 표현식이 특정 컬렉션의 객체에 존재하지 않는 "쿼리 가능 필드"를 사용하는 경우 컬렉션별 역할을 제공하여 해당 컬렉션에 대한 규칙을 재정의할 수 있습니다. 자세한 내용은 역할 기반 권한을 참조하세요.
자신의 데이터 읽기 및 쓰기
이 경우 사용자는 자신의 데이터는 읽거나 쓸 수 있지만 다른 사용자의 데이터는 읽을 수 없습니다. 사용자가 자신의 기기에서 메모를 보관하고 공유하면서도 사용자 계정에서 메모를 비공개로 유지하려는 메모 앱을 가정해 보겠습니다.
이 전략을 사용하면 문서의 owner_id
필드가 사용자 ID와 같은 경우에만 사용자가 문서를 만들고 편집할 수 있습니다.
"자체 데이터 읽기 및 쓰기" 전략을 설정하려면 일반적인 단계를 따르세요.
Realm UI에 로그인한 다음 왼쪽 패널에서 Sync를 클릭합니다.
Sync Type에서 Flexible을 선택합니다.
Development Mode 토글을 활성화로 설정합니다.
동기화하려는 클러스터를 선택합니다.
Define a Database Name: +Add a new database를 선택하고 Realm에서 동기화된 객체를 저장하는 데 사용할 데이터베이스의 이름을 입력합니다. 원하는 이름을 지정할 수 있습니다. 만들고 있는 앱의 이름을 따서 데이터베이스 이름을 짓는 것이 일반적인 전략입니다.
Select Queryable Fields:
owner_id
를 입력합니다. 이렇게 하면 다음에 설정하게 될 권한 표현식에서owner_id
인 모든 필드를 사용할 수 있습니다.Advanced Configuration을 건너뛴 다음 Save Changes을 클릭하여 Sync를 활성화합니다.
이제 권한을 구성해야 합니다. Rules 페이지로 이동합니다. 기본 역할을 수정하려면 Default Roles and Filters 버튼을 클릭합니다. 템플릿 드롭다운을 사용하여 "사용자는 자신의 데이터만 읽고 쓸 수 있음"이라는 템플릿을 선택합니다.
그러면 규칙 표현식 상자가 다음과 같이 채워집니다.
{ "name": "owner-read-write", "apply_when": {}, "document_filters": { "read": { "owner_id": "%%user.id" }, "write": { "owner_id": "%%user.id" } }, "read": true, "write": true }
document_filters.read
및 document_filters.write
표현식은 위에서 "쿼리 가능"으로 표시한 owner_id
필드를 사용한다는 점에 유의하세요. 또한 여기서는 %%user
확장을 사용하여 요청하는 사용자의 ID를 읽습니다. App Services는 평가 시 확장자를 해당 값(이 경우에는 사용자 객체)으로 대체 (또는 "확장")합니다.
지정된 문서에 대한 권한을 평가할 때 App Services는 해당 최상위 수준 read
또는 write
표현식보다 document_filters.read
및 document_filters.write
를 먼저 확인합니다. 예를 들어 document_filters.write
값이 false로 평가되면 쓰기 액세스가 거부되고 후속 규칙은 확인되지 않습니다. 그러나 document_filters.write
가 true로 평가되면 App Services는 최상위 수준 write
표현식을 확인합니다. 이 경우 write
가 true
이므로 전체 문서에 대해 쓰기 권한이 부여됩니다. 자세한 내용은 Device Sync-호환 권한을 참조하세요.
자신의 데이터 쓰기, 모든 데이터 읽기
이 경우 사용자는 모든 데이터를 읽을 수는 있지만 자신의 데이터만 쓸 수 있습니다. 사용자가 모든 레시피를 읽고 새 레시피를 추가할 수 있는 레시피 앱을 생각해 보세요. 추가한 레시피는 앱을 사용하는 모든 사람이 볼 수 있습니다. 사용자는 자신이 제공한 레시피만 업데이트하거나 삭제할 수 있습니다.
"자신의 데이터 쓰기, 모든 데이터 읽기" 전략을 설정하려면 다음과 같은 일반적인 단계를 따르세요.
Realm UI에 로그인한 다음 왼쪽 패널에서 Sync를 클릭합니다.
Sync Type에서 Flexible을 선택합니다.
Development Mode 토글을 활성화로 설정합니다.
동기화하려는 클러스터를 선택합니다.
Define a Database Name: +Add a new database를 선택하고 Realm에서 동기화된 객체를 저장하는 데 사용할 데이터베이스의 이름을 입력합니다. 원하는 이름을 지정할 수 있습니다. 만들고 있는 앱의 이름을 따서 데이터베이스 이름을 짓는 것이 일반적인 전략입니다.
Select Queryable Fields:
owner_id
를 입력합니다. 이렇게 하면 다음에 설정하게 될 권한 표현식에서owner_id
인 모든 필드를 사용할 수 있습니다.Advanced Configuration을 건너뛴 다음 Save Changes을 클릭하여 Sync를 활성화합니다.
이제 권한을 구성해야 합니다. Rules 페이지로 이동합니다. 기본 역할을 수정하려면 Default Roles and Filters 버튼을 클릭합니다. 템플릿 드롭다운을 사용하여 "사용자는 모든 데이터를 읽을 수 있지만 자신의 데이터만 쓸 수 있음"이라는 템플릿을 선택합니다.
그러면 규칙 표현식 상자가 다음과 같이 채워집니다.
{ "name": "owner-write", "apply_when": {}, "document_filters": { "read": true, "write": { "owner_id": "%%user.id" } }, "read": true, "write": true }
참고로 document_filters.read
표현식은 true
로 설정되어 사용자가 인증 여부와 관계없이 모든 데이터를 읽을 수 있음을 나타냅니다. document_filters.write
표현식은 위에서 "쿼리 가능"으로 표시한 owner_id
필드를 사용하고 %%user
확장자를 사용하여 요청한 사용자의 ID와 일치시킵니다. App Services는 평가 시 확장자를 해당 값(이 경우에는 사용자 객체)으로 대체 ("확장")합니다.
App Services는 document_filters.write
가 true로 평가되는 경우에만 최상위 write
표현식을 확인합니다. document_filters.write
가 false로 평가되면 최상위 write
표현식의 내용에 관계없이 쓰기 액세스가 거부됩니다. 자세한 내용은 Device Sync-호환 권한을 참조하세요.
관리자 권한
이 권한 전략에서는 특정 "관리자" 역할을 가진 사용자가 모든 문서를 읽고 쓸 수 있습니다. 지정된 역할이 없는 사용자는 자신의 데이터만 읽고 쓸 수 있습니다. 이 전략을 실행하려면 먼저 관리자 권한이 있는 사용자를 정의해야 합니다.
Atlas Apps를 사용하면 Atlas의 사용자 지정 사용자 데이터를 애플리케이션 사용자와 연결할 수 있습니다. 이 기능을 사용하면 사용자에게 관리자 권한이 있는지 여부를 나타내는 필드가 포함된 문서를 만들 수 있습니다. 이를 설정하는 방법은 여러 가지가 있지만, 한 가지 방법은 상승된 권한을 가진 사용자에 대해 isGlobalAdmin
이라는 부울 속성을 추가하고 이를 true
로 설정하는 것입니다. 또 다른 방법은 예상 값 중 하나가 "admin"일 수 있는 role
이라는 문자열 필드를 만드는 것입니다.
다음 예시에서 만들 사용자 지정 사용자 객체에는 사용자의 ID에 해당하는 _id
필드와 firstName
, lastName
및 isGlobalAdmin
이라는 추가 필드 3개가 있습니다.
{ "_id" : "1234", "firstName": "Lily", "lastName": "Realmster", "isGlobalAdmin": true }
참고
권한에 사용자 지정 사용자 데이터를 사용하는 경우 클라이언트가 사용자 지정 사용자 데이터 객체를 작성하도록 허용하지 않아야 합니다. 이 권한을 허용하면 모든 사용자가 자신에게 모든 권한을 부여할 수 있습니다. 대신 서버 측의 시스템 기능을 사용하여 사용자 지정 사용자 데이터 객체를 업데이트하세요.
사용자 지정 사용자 데이터 활성화 및 구성
Atlas App Services는 사용자 지정 사용자 데이터에 해당하는 MongoDB 문서를 연결된 MongoDB Atlas 클러스터에 저장합니다. 애플리케이션에 대한 사용자 지정 사용자 데이터를 구성할 때 클러스터, 데이터베이스, 컬렉션을 지정하고 마지막으로 사용자 지정 사용자 데이터 문서를 인증된 사용자의 ID에 매핑하는 사용자 ID 필드를 지정합니다.
App Services UI에서 사용자 지정 사용자 데이터를 활성화하려면 다음 단계를 따릅니다.
왼쪽 패널에서 App Users 를 클릭합니다.
User Settings 탭을 선택하고 Custom User Data 섹션을 찾습니다.
Enable Custom User Data 토글을 On 으로 설정합니다.
다음 값을 지정합니다.
Cluster Name: 사용자 지정 사용자 데이터 데이터베이스를 포함할 연결된 MongoDB 클러스터의 이름입니다.
Database Name: 사용자 지정 사용자 데이터 컬렉션을 포함할 MongoDB 데이터베이스의 이름입니다.
Collection Name: 사용자 지정 사용자 데이터가 포함된 MongoDB 컬렉션의 이름입니다.
사용자 ID 필드를 지정합니다. 사용자 지정 사용자 데이터 컬렉션의 모든 문서에는 특정 사용자에 매핑되는 필드가 있어야 합니다. 이 필드는 사용자에게 매핑되는 모든 문서에 포함되어야 하며, 사용자 ID를 문자열로 포함해야 합니다. 사용자 ID를 저장하려면 표준
_id
필드를 사용하는 것이 좋습니다. MongoDB는_id
필드에 자동으로 제약 조건을 설정하여 고유성을 보장합니다.참고
이 컬렉션에 있는 두 문서에 동일한 사용자 ID 값이 포함되어 있으면 App Services에서 일치하는 첫 번째 문서를 사용하므로 예기치 않은 결과가 발생합니다.
변경 사항을 저장하고 배포합니다.
참고
사용자 지정 사용자 데이터 업데이트 후 동기화 세션 다시 시작하기
동기화 서버는 세션이 진행되는 동안 사용자 지정 사용자 데이터를 캐시합니다. 따라서 사용자 지정 사용자 데이터를 업데이트한 후 동기화 세션을 다시 시작해야 보상 쓰기 오류를 방지할 수 있습니다. 동기화 세션을 다시 시작하려면 클라이언트 애플리케이션에서 열려 있는 모든 동기화 세션을 일시 중지했다가 다시 시작하세요. 클라이언트 SDK에서 동기화를 일시 중지하고 다시 시작하는 방법에 대한 자세한 내용은 자주 사용하는 SDK를 참조하세요.
관리자 권한 설정
사용자 지정 사용자 데이터를 활성화한 후 관리자 권한 전략을 구현할 수 있습니다. 이렇게 하려면 다음과 같은 일반적인 단계를 따르세요.
Realm UI에 로그인한 다음 왼쪽 패널에서 Sync를 클릭합니다.
Sync Type에서 Flexible을 선택합니다.
Development Mode 토글을 활성화로 설정합니다.
동기화하려는 클러스터를 선택합니다.
Define a Database Name: +Add a new database를 선택하고 Realm에서 동기화된 객체를 저장하는 데 사용할 데이터베이스의 이름을 입력합니다. 원하는 이름을 지정할 수 있습니다. 만들고 있는 앱의 이름을 따서 데이터베이스 이름을 짓는 것이 일반적인 전략입니다.
Select Queryable Fields:
owner_id
를 입력합니다. 이렇게 하면 다음에 설정하게 될 권한 표현식에서owner_id
인 모든 필드를 사용할 수 있습니다.Advanced Configuration을 건너뛴 다음 Save Changes을 클릭하여 Sync를 활성화합니다.
이제 권한을 구성해야 합니다. Rules 페이지로 이동합니다. 기본 역할을 수정하려면 Default Roles and Filters 버튼을 클릭합니다. 템플릿 드롭다운을 사용하여 "사용자는 자신의 데이터만 읽고 쓸 수 있음, 관리자는 모든 데이터 읽고 쓸 수 있음"이라는 템플릿을 선택합니다.
그러면 규칙 표현식 상자가 다음과 같이 채워집니다.
[ { "name": "admin", "apply_when": { "%%user.custom_data.isGlobalAdmin": true }, "document_filters": { "read": true, "write": true }, "read": true, "write": true }, { "name": "user", "apply_when": {}, "document_filters": { "read": { "owner_id": "%%user.id" }, "write": { "owner_id": "%%user.id" } }, "read": true, "write": true } ]
참고
기본 설정 변경
이 구성에는 두 가지 기본 역할이 있습니다. 첫 번째는 관리자에 대한 권한을 정의합니다. 자동 생성된 표현식은 사용자 지정 사용자 데이터 문서에 isGlobalAdmin
라는 부울 필드가 있다고 가정합니다. 사용자 지정 사용자 데이터 문서를 정의한 방법에 따라 이를 변경해야 할 수 있습니다.
두 번째 기본 역할은 다른 모든 사용자에 대한 규칙을 지정합니다. 기본값은 사용자가 자신의 데이터만 읽고 쓰도록 액세스를 제한하는 것입니다. 이 필드 중 하나 또는 둘 다를 true
로 변경하여 사용자가 모든 데이터를 읽거나 쓸 수 있도록 할 수 있습니다. 이러한 전략에 대해 자세히 알아보려면 이전 섹션을 참조하세요.
제한된 뉴스 피드
참고
템플릿 사용 가능!
백엔드 템플릿을 사용하고 데모 클라이언트를 가져오려면 다음 명령을 실행하세요.
appservices apps create --name=restricted-feed --template=flex-sync-guides.restricted-feed
사용자 지정 사용자 데이터 구성 버그 해결 방법: 템플릿 생성기가 사용자 지정 사용자 데이터 구성을 새 앱에 올바르게 복사하지 않는 경우가 있습니다. 이 문제를 수정하는 방법은 다음과 같습니다. appservices apps create
명령은 방금 만든 앱에 대한 일부 JSON을 출력해야 합니다. 이 JSON에서 "url" 값(예: https://services.cloud.mongodb.com/groups/...
)을 복사하고 브라우저에서 해당 URL을 방문하세요. 메시지가 표시되면 로그인합니다. 앱 대시보드의 왼쪽 패널에서 App Users을 클릭합니다. Custom
User Data를 클릭합니다. Enable Custom User Data가 ON
인지 확인합니다. 켜져 있지 않은 경우 이를 켜고 Cluster Name, Database Name 및 Collection
Name에 대해 각각 "mongodb-atlas", "Item" 및 "User"를 입력합니다. User ID Field에 _id
를 입력합니다. Save (또는 Save Draft를 누른 다음 배포).
그런 다음 터미널에서 클라이언트 디렉토리로 이동하여 종속성을 설치하고 데모를 실행합니다.
cd restricted-feed/frontend/flex-sync-guides.restricted-feed/ npm install npm run demo
콘솔에서 출력을 읽어 데모가 어떻게 작동하는지 확인하세요.
이 권한 전략에서 사용자는 자신의 콘텐츠를 만들고 다른 제작자의 콘텐츠를 구독할 수 있습니다. 관리자 권한 시나리오와 마찬가지로 사용자 지정 사용자 데이터 컬렉션을 사용하여 사용자가 어떤 작성자의 콘텐츠를 구독하여 읽을 수 있는지 정의합니다.
유연한 Device Sync는 배열 쿼리를 지원하므로 사용자 데이터 객체 내에 배열을 생성합니다. 이 배열에는 이 사용자가 "팔로우"할 수 있는 권한이 있는 작성자의 ID가 포함되어 있습니다. 그런 다음 기본적으로 "내가 작성자인 모든 문서 또는 작성자의 ID가 사용자 지정 사용자 데이터의 작성자 배열에 포함된 모든 문서 반환"이라는 구독을 설정합니다.
중요
사용자가 작성자를 구독하거나 구독을 취소하면 사용자 지정 사용자 데이터의 배열이 업데이트되지만, 현재 세션이 종료되고 새 세션이 시작될 때까지 변경 사항은 적용되지 않습니다.
참고
크기 제한
이 예에서는 사용자 지정 사용자 데이터에 배열을 생성합니다. App Services는 이 배열의 크기를 제한하지 않지만, 각 요청에 데이터가 포함되므로 128비트 GUID 스타일 사용자 ID 1000개를 위한 충분한 공간인 16KB 미만으로 유지하는 것이 좋습니다.
참고
권한에 사용자 지정 사용자 데이터를 사용하는 경우 클라이언트가 사용자 지정 사용자 데이터 객체를 작성하도록 허용하지 않아야 합니다. 이 권한을 허용하면 모든 사용자가 자신에게 모든 권한을 부여할 수 있습니다. 대신 서버 측의 시스템 기능을 사용하여 사용자 지정 사용자 데이터 객체를 업데이트하세요.
사용자 지정 사용자 데이터 활성화 및 구성
App Services UI에서 사용자 지정 사용자 데이터를 활성화하려면 다음 단계를 따릅니다.
왼쪽 패널에서 App Users 를 클릭합니다.
User Settings 탭을 선택하고 Custom User Data 섹션을 찾습니다.
Enable Custom User Data 토글을 On 으로 설정합니다.
다음 값을 지정합니다.
Cluster Name: 사용자 지정 사용자 데이터 데이터베이스를 포함할 연결된 MongoDB 클러스터의 이름입니다.
Database Name: 사용자 지정 사용자 데이터 컬렉션을 포함할 MongoDB 데이터베이스의 이름입니다.
Collection Name: 사용자 지정 사용자 데이터가 포함된 MongoDB 컬렉션의 이름입니다.
사용자 ID 필드를 지정합니다. 사용자 지정 사용자 데이터 컬렉션의 모든 문서에는 특정 사용자에 매핑되는 필드가 있어야 합니다. 이 필드는 사용자에게 매핑되는 모든 문서에 포함되어야 하며, 사용자 ID를 문자열로 포함해야 합니다. 사용자 ID를 저장하려면 표준
_id
필드를 사용하는 것이 좋습니다. MongoDB는_id
필드에 자동으로 제약 조건을 설정하여 고유성을 보장합니다.참고
이 컬렉션에 있는 두 문서에 동일한 사용자 ID 값이 포함되어 있으면 App Services에서 일치하는 첫 번째 문서를 사용하므로 예기치 않은 결과가 발생합니다.
변경 사항을 저장하고 배포합니다.
참고
사용자 지정 사용자 데이터 업데이트 후 동기화 세션 다시 시작하기
동기화 서버는 세션이 진행되는 동안 사용자 지정 사용자 데이터를 캐시합니다. 따라서 사용자 지정 사용자 데이터를 업데이트한 후 동기화 세션을 다시 시작해야 보상 쓰기 오류를 방지할 수 있습니다. 동기화 세션을 다시 시작하려면 클라이언트 애플리케이션에서 열려 있는 모든 동기화 세션을 일시 중지했다가 다시 시작하세요. 클라이언트 SDK에서 동기화를 일시 중지하고 다시 시작하는 방법에 대한 자세한 내용은 자주 사용하는 SDK를 참조하세요.
인증 트리거 함수 생성
사용자가 처음 인증할 때 사용자 지정 사용자 객체를 생성하는 인증 트리거 함수를 만들어야 합니다. 이렇게 하려면 다음 단계를 따라 진행합니다.
Realm UI에 로그인한 다음 왼쪽 패널에서 Triggers를 클릭합니다.
Add a Trigger 버튼을 클릭합니다.
Trigger Type 토글을 Authentication 으로 설정합니다.
Triggers 세부 정보에서 다음 값을 지정합니다.
Name: "onUserCreated"
Enbaled: 토글을 "켜짐"으로 전환합니다.
Action Type: "만들기"를 선택합니다.
Provider(s): "이메일/비밀번호" 또는 사용 중인 인증 제공자를 선택합니다.
Select an Event Type: "기능"을 선택합니다.
Function: " +새 기능"을 선택합니다:
Function Name: "onUserCreated"
Function: 자리 표시자 텍스트를 다음 함수로 바꿉니다.
exports = function(authEvent) { const user = authEvent.user; const collection = context.services.get("mongodb-atlas").db("Item").collection("User"); const newDoc = { _id: user.id, email: user.data.email, // Useful for looking up user IDs by email later - assuming email/password auth is used team: "", // Used for tiered privileges isTeamAdmin: false, // Used for tiered privileges isGlobalAdmin: false, // Used for admin privileges subscribedTo: [], // Used for restricted feed }; return collection.insertOne(newDoc); };
제한된 권한 설정
사용자 지정 사용자 데이터 객체에서 사용자가 팔로우하는 각 작성자의 _id 값을 보유하는 배열을 만듭니다. 이 예에서는 "구독"이라고 부르겠습니다. 사용자 데이터 객체는 다음과 같이 표시되며, 여기서 Lily Realmster("_id": "1234"
)는 사용자 "456" 및 "789" 이 작성한 모든 문서를 구독합니다.
{ "_id" : "1234", "firstName": "Lily", "lastName": "Realmster", "user.custom_data.subscribedTo": [ "456", "789" ] }
이제 제한된 권한 전략을 구현할 수 있습니다. 이렇게 하려면 다음과 같은 일반적인 단계를 따르세요.
Realm UI에 로그인한 다음 왼쪽 패널에서 Sync를 클릭합니다.
Sync Type에서 Flexible을 선택합니다.
Development Mode 토글을 활성화로 설정합니다.
동기화하려는 클러스터를 선택합니다.
Define a Database Name: +Add a new database를 선택하고 Realm에서 동기화된 객체를 저장하는 데 사용할 데이터베이스의 이름을 입력합니다. 원하는 이름을 지정할 수 있습니다. 만들고 있는 앱의 이름을 따서 데이터베이스 이름을 짓는 것이 일반적인 전략입니다.
Select Queryable Fields:
owner_id
를 입력합니다. 이렇게 하면 다음에 설정하게 될 권한 표현식에서owner_id
인 모든 필드를 사용할 수 있습니다.Advanced Configuration을 건너뛴 다음 Save Changes을 클릭하여 Sync를 활성화합니다.
이제 권한을 구성해야 합니다. Rules 페이지로 이동합니다. 기본 역할을 수정하려면 Default Roles and Filters 버튼을 클릭합니다. 템플릿 드롭다운을 사용하여 "사용자는 자신의 데이터만 읽고 쓸 수 있음"이라는 템플릿을 선택합니다. 이렇게 하면 규칙 표현식 상자가 다음과 같이 채워지는데, 우리가 원하는 것과 정확히 일치하지는 않지만 대부분의 논리를 제공합니다.
{ "name": "owner-read-write", "apply_when": {}, "document_filters": { "read": { "owner_id": "%%user.id" }, "write": { "owner_id": "%%user.id" } }, "read": true, "write": true }
사용자는 현재 자신의 문서("read":
{"owner_id": "%%user.id"}
)만 읽을 수 있습니다. 작성자가 사용자의 "SubscribeDto" 배열에 ID를 가진 문서를 포함하도록 변경할 수 있습니다. 이를 위해 $in
연산자를 사용합니다. 표현식은 다음과 같습니다.
{ "name": "owner-read-write", "apply_when": {}, "document_filters": { "read": { "owner_id": { "$in": "%%user.custom_data.subscribedTo" } }, "write": { "owner_id": "%%user.id" } }, "read": true, "write": true }
규칙 표현식 상자를 이 새 로직으로 업데이트하고 변경 내용을 저장합니다.
참고: document_filters.read
표현식을 구독자 배열의 작성자만 언급하도록 변경했지만, document_filters.read
표현식으로 인해 사용자는 여전히 "읽기" 자신의 문서에 대한 액세스 권한을 가집니다. 쓰기 액세스가 부여될 때마다 읽기 액세스가 암시적으로 부여됩니다.
subscribeToUser 함수 생성
한 사용자를 다른 사용자에 구독하는 기능이 필요합니다. 작성자의 사용자 ID가 구독자의 사용자 지정 사용자 데이터 "subscribedTo" 배열에 있는 경우, 구독자가 작성자를 "구독"한 것으로 간주하도록 권한이 설정됩니다. "subscribeToUser" 함수는 사용자의 이메일 주소를 가져와 사용자 지정 사용자 데이터 컬렉션에서 해당 사용자 ID를 찾은 다음, 요청 사용자의 "subscribedTo" 배열에 해당 ID를 추가합니다.
이 함수는 시스템 인증 하에 실행 되며 사용자 지정 사용자 데이터 에 기록됩니다. 권한에 사용자 지정 사용자 데이터 를 사용하는 경우 클라이언트가 사용자 지정 사용자 데이터 를 직접 편집하도록 허용해서는 안 됩니다. 그렇지 않으면 모든 사용자가 자신에게 모든 권한을 부여할 수 있습니다. 대신 시스템 함수를 사용하여 백엔드 에서 사용자 데이터를 수정하세요. 이 함수는 사용자의 권한 요청 이 유효한지 확인하는 데 필요한 모든 검사를 수행해야 합니다.
함수를 만들려면 다음 단계를 따르세요.
Realm UI에 로그인한 다음 왼쪽 패널에서 Functions를 클릭합니다.
Create New Function 버튼을 클릭합니다.
다음 값을 지정합니다.
Name: "subscribeToUser"
Authentication: "System"
Function Editor 탭으로 전환하고 자리 표시자 텍스트를 다음 코드로 바꿉니다.
exports = async function(email) { const collection = context.services.get("mongodb-atlas").db("Item").collection("User"); // Look up the author object to get the user id from an email const author = await collection.findOne({email}); if (author == null) { return {error: `Author ${email} not found`}; } // Whoever called this function is the would-be subscriber const subscriber = context.user; try { return await collection.updateOne( {_id: subscriber.id}, {$addToSet: { subscribedTo: author._id, } }); } catch (error) { return {error: error.toString()}; } };
동적 협업
참고
템플릿 사용 가능!
백엔드 템플릿을 사용하고 데모 클라이언트를 가져오려면 다음 명령을 실행하세요.
appservices apps create --name=add-collaborators --template=flex-sync-guides.add-collaborators
그런 다음 클라이언트 디렉토리로 이동하여 종속 요소를 설치하고 데모를 실행합니다.
cd add-collaborators/frontend/flex-sync-guides.add-collaborators/ npm install npm run demo
콘솔에서 출력을 읽어 데모가 어떻게 작동하는지 확인하세요.
동적 협업 전략에서 사용자가 문서를 만들고 다른 사용자를 해당 문서의 편집자로 추가할 수 있습니다.
자신의 데이터 읽기 및 쓰기 전략과 마찬가지로, 이 전략을 사용하면 문서의 owner_id
필드가 사용자 ID와 동일한 경우 사용자가 문서를 생성하고 편집할 수 있습니다. 또한 문서의 collaborators
배열 필드에 ID가 포함된 경우 사용자가 문서를 편집할 수 있습니다.
권한 설정
이 전략을 구현하려면 다음과 같은 일반적인 단계를 따르세요:
Realm UI에 로그인한 다음 왼쪽 패널에서 Sync를 클릭합니다.
Sync Type에서 Flexible을 선택합니다.
Development Mode 토글을 활성화로 설정합니다.
동기화하려는 클러스터를 선택합니다.
Define a Database Name: +Add a new database를 선택하고 Realm에서 동기화된 객체를 저장하는 데 사용할 데이터베이스의 이름을 입력합니다. 원하는 이름을 지정할 수 있습니다. 만들고 있는 앱의 이름을 따서 데이터베이스 이름을 짓는 것이 일반적인 전략입니다.
Select Queryable Fields:
owner_id
를 입력합니다. 이렇게 하면 다음에 설정하게 될 권한 표현식에서owner_id
인 모든 필드를 사용할 수 있습니다.Advanced Configuration을 건너뛴 다음 Save Changes을 클릭하여 Sync를 활성화합니다.
Select Queryable Fields 필드에 collaborators
도 입력합니다. 이 필드는 문서를 읽고 쓸 수 있는 사용자의 ID를 저장하는 필드입니다.
이제 권한을 구성해야 합니다. Define Permissions에서 템플릿 드롭다운을 사용하여 "사용자 지정(처음부터 시작)"을 선택합니다. 규칙 표현식 상자에 다음을 붙여넣습니다.
{ "name": "collaborator", "apply_when": {}, "document_filters": { "read": { "$or": [ { "owner_id": "%%user.id" }, { "collaborators": "%%user.id" } ] }, "write": { "$or": [ { "owner_id": "%%user.id" }, { "collaborators": "%%user.id" } ] } }, "read": true, "write": true }
"쓰기" 및 "읽기" 표현식은 동일합니다. 그 중 하나를 살펴보세요. $or
는 옵션 배열을 사용합니다. 사용자가 문서를 작성할 수 있는 두 가지 가능한 조건은 다음과 같습니다.
문서의
owner_id
필드가 사용자의 ID와 같습니다.문서의
collaborators
배열 필드에 사용자 ID가 포함되어 있습니다.
일반적으로 사용자에게 쓰기 권한이 부여되면 해당 사용자는 자동으로 읽기 권한을 얻습니다. 그러나 App Services에서는 역할이 동기화 호환되도록 정의하기 위해 document_filters.read
및 document_filters.write
가 모두 필요하므로 document_filters.read
표현식을 생략할 수 없습니다.
협업자 추가하기
사용자는 문서의 collaborators
배열 필드에 해당 사용자 ID를 추가하여 다른 사용자에게 문서에 대한 쓰기 액세스 권한을 부여할 수 있습니다. 클라이언트 사이드에서 이 작업을 수행할 수 있습니다.
보안
매우 중요한 데이터에는 이 모델을 사용하지 않는 것이 좋습니다.
이 모델은 권한 시스템을 사용하여 문서 작성자와 문서에 추가하는 협업자 사이에서 문서를 비공개로 유지합니다. 그러나 사용자가 문서에 대한 쓰기 액세스 권한을 갖고 있는 경우 문서의 모든 필드에 쓸 수 있습니다. 따라서 이 전략을 사용하면 협업자가 다른 협업자를 추가할 수 있습니다. 또한 공동 작업자가 owner_id
필드를 수정할 수 있습니다. 필드 수준 권한은 동기화 호환을 위해 부울 리터럴이어야 하므로 이러한 필드에 대한 쓰기를 특정 사용자로 제한할 수 없습니다.
사용자 검색
다른 사용자의 ID를 정확히 가져오는 방법은 앱의 세부 정보에 따라 다릅니다. 예를 들어, 사용자가 문서에 다른 사용자를 추가하려는 경우 이메일 주소를 허용하는 검색창이 있을 수 있습니다. 지정된 이메일 주소가 다른 사용자와 일치하는 경우 클라이언트는 해당 사용자의 ID를 문서의 collaborators
배열에 추가할 수 있습니다.
Realm에는 사용자를 검색하는 기본 제공 방법이 없습니다. 일반적으로 사용자를 검색하는 흐름은 다음과 같습니다.
사용자가 등록할 때 사용자 문서를 생성하도록 인증 트리거를 설정합니다. 사용자 문서에는 사용자의 이메일 주소와 같이 나중에 검색하는 데 사용할 정보가 들어 있습니다.
사용자에 대한 사용자 데이터 컬렉션을 쿼리하는 함수를 만듭니다.
사용자가 다른 사용자를 찾고자 할 때 클라이언트 사이드에서 함수를 호출합니다.
인증 트리거를 만들려면 다음 단계를 수행합니다.
Realm UI에 로그인한 다음 왼쪽 패널에서 Triggers를 클릭합니다.
Add a Trigger 버튼을 클릭합니다.
Trigger Type 토글을 Authentication 으로 설정합니다.
Triggers 세부 정보에서 다음 값을 지정합니다.
Name: "onUserCreated"
Enbaled: 토글을 "켜짐"으로 전환합니다.
Action Type: "만들기"를 선택합니다.
Provider(s): "이메일/비밀번호" 또는 사용 중인 인증 제공자를 선택합니다.
Select an Event Type: "기능"을 선택합니다.
Function: " +새 기능"을 선택합니다:
Function Name: "onUserCreated"
Function: 자리 표시자 텍스트를 다음 함수로 바꿉니다.
exports = function(authEvent) { const user = authEvent.user; const collection = context.services.get("mongodb-atlas").db("Item").collection("User"); const newDoc = { _id: user.id, email: user.data.email, // Useful for looking up user IDs by email later - assuming email/password auth is used team: "", // Used for tiered privileges isTeamAdmin: false, // Used for tiered privileges isGlobalAdmin: false, // Used for admin privileges subscribedTo: [], // Used for restricted feed }; return collection.insertOne(newDoc); };
다음으로 findUser
이라는 시스템 기능을 만듭니다.
Realm UI에 로그인하고 Realm 앱으로 이동한 다음 왼쪽 패널에서 Functions를 클릭합니다.
Create New Function 버튼을 클릭합니다.
함수에 대한 설명 Name을 입력합니다.
Authentication: System을 선택합니다. 이를 통해 함수가 컬렉션에 대한 권한을 우회할 수 있습니다.
Log Function Arguments
off
로 둡니다.Authorization:
Can Evaluate: 비워 둡니다.
Private
off
로 둡니다.
Save를 클릭합니다. 이제 실행할 항목을 입력할 수 있는 Function Editor로 이동합니다.
경고
이 구성을 사용하면 누구나 이 함수를 호출할 수 있습니다. 시스템 기능으로서 이 함수는 액세스 규칙을 우회합니다. 이 함수를 호출하는 클라이언트가 악의적인 의도를 가지고 있다고 가정합니다.
Function Editor0}에 다음 코드를 붙여넣고 저장합니다:
exports = async function(email) { const collection = context.services.get("mongodb-atlas") .db("Item").collection("User"); const filter = { email, }; // Search for the user by email const result = await collection.findOne(filter); // Return corresponding user id or null return result != null ? result._id : null; };
이제 클라이언트에서 이 함수를 호출할 수 있습니다. 함수의 유일한 인수는 이메일 주소 문자열입니다. 이메일이 사용자에 해당하는 경우 이 함수는 사용자의 ID를 반환합니다. 그렇지 않으면 null을 반환합니다.
계층화된 권한
참고
템플릿 사용 가능!
백엔드 템플릿을 사용하고 데모 클라이언트를 가져오려면 다음 명령을 실행하세요.
appservices apps create --name=tiered --template=flex-sync-guides.tiered
사용자 지정 사용자 데이터 구성 버그 해결 방법: 템플릿 생성기가 사용자 지정 사용자 데이터 구성을 새 앱에 올바르게 복사하지 않는 경우가 있습니다. 이 문제를 수정하는 방법은 다음과 같습니다. appservices apps create
명령은 방금 만든 앱에 대한 일부 JSON을 출력해야 합니다. 이 JSON에서 "url" 값(예: https://services.cloud.mongodb.com/groups/...
)을 복사하고 브라우저에서 해당 URL을 방문하세요. 메시지가 표시되면 로그인합니다. 앱 대시보드의 왼쪽 패널에서 App Users을 클릭합니다. Custom
User Data를 클릭합니다. Enable Custom User Data가 ON
인지 확인합니다. 켜져 있지 않은 경우 이를 켜고 Cluster Name, Database Name 및 Collection
Name에 대해 각각 "mongodb-atlas", "Item" 및 "User"를 입력합니다. User ID Field에 _id
를 입력합니다. Save (또는 Save Draft를 누른 다음 배포).
그런 다음 터미널에서 클라이언트 디렉토리로 이동하여 종속성을 설치하고 데모를 실행합니다.
cd tiered/frontend/flex-sync-guides.tiered/ npm install npm run demo
콘솔에서 출력을 읽어 데모가 어떻게 작동하는지 확인하세요.
이 권한 전략에서는 규칙뿐만 아니라 특수 역할도 추가할 것입니다. 팀 멤버와 팀 관리자라는 두 가지 역할이 있습니다. 규칙은 다음과 같습니다:
각 사용자는 팀의 구성원입니다.
사용자는 자신의 문서를 읽고 쓸 수 있습니다.
팀의 모든 구성원은 팀 구성원이 작성한 모든 문서를 읽을 수 있습니다.
각 팀에는 모든 팀 문서에 대한 읽기 및 쓰기 권한이 있는 팀 관리자가 있습니다.
이 작업을 수행하려면 다음을 수행해야 합니다:
사용자 지정 사용자 데이터 활성화
각 새 사용자에 대해 새 사용자 지정 데이터 객체를 만드는 트리거 함수를 만듭니다.
팀에 사용자를 추가하는 함수 만들기
권한 정의
참고
권한에 사용자 지정 사용자 데이터를 사용하는 경우 클라이언트가 사용자 지정 사용자 데이터 객체를 작성하도록 허용하지 않아야 합니다. 이 권한을 허용하면 모든 사용자가 자신에게 모든 권한을 부여할 수 있습니다. 대신 서버 측의 시스템 기능을 사용하여 사용자 지정 사용자 데이터 객체를 업데이트하세요.
사용자 지정 사용자 데이터 활성화 및 구성
App Services UI에서 사용자 지정 사용자 데이터를 활성화하려면 다음 단계를 따릅니다.
왼쪽 패널에서 App Users 를 클릭합니다.
User Settings 탭을 선택하고 Custom User Data 섹션을 찾습니다.
Enable Custom User Data 토글을 On 으로 설정합니다.
다음 값을 지정합니다.
Cluster Name: 사용자 지정 사용자 데이터 데이터베이스를 포함할 연결된 MongoDB 클러스터의 이름입니다.
Database Name: 사용자 지정 사용자 데이터 컬렉션을 포함할 MongoDB 데이터베이스의 이름입니다.
Collection Name: 사용자 지정 사용자 데이터가 포함된 MongoDB 컬렉션의 이름입니다.
사용자 ID 필드를 지정합니다. 사용자 지정 사용자 데이터 컬렉션의 모든 문서에는 특정 사용자에 매핑되는 필드가 있어야 합니다. 이 필드는 사용자에게 매핑되는 모든 문서에 포함되어야 하며, 사용자 ID를 문자열로 포함해야 합니다. 사용자 ID를 저장하려면 표준
_id
필드를 사용하는 것이 좋습니다. MongoDB는_id
필드에 자동으로 제약 조건을 설정하여 고유성을 보장합니다.참고
이 컬렉션에 있는 두 문서에 동일한 사용자 ID 값이 포함되어 있으면 App Services에서 일치하는 첫 번째 문서를 사용하므로 예기치 않은 결과가 발생합니다.
변경 사항을 저장하고 배포합니다.
참고
사용자 지정 사용자 데이터 업데이트 후 동기화 세션 다시 시작하기
동기화 서버는 세션이 진행되는 동안 사용자 지정 사용자 데이터를 캐시합니다. 따라서 사용자 지정 사용자 데이터를 업데이트한 후 동기화 세션을 다시 시작해야 보상 쓰기 오류를 방지할 수 있습니다. 동기화 세션을 다시 시작하려면 클라이언트 애플리케이션에서 열려 있는 모든 동기화 세션을 일시 중지했다가 다시 시작하세요. 클라이언트 SDK에서 동기화를 일시 중지하고 다시 시작하는 방법에 대한 자세한 내용은 자주 사용하는 SDK를 참조하세요.
인증 트리거 함수 생성
사용자가 처음 인증할 때 사용자 지정 사용자 객체를 생성하는 인증 트리거 함수를 만들어야 합니다. 이렇게 하려면 다음 단계를 따라 진행합니다.
Realm UI에 로그인한 다음 왼쪽 패널에서 Triggers를 클릭합니다.
Add a Trigger 버튼을 클릭합니다.
Trigger Type 토글을 Authentication 으로 설정합니다.
Triggers 세부 정보에서 다음 값을 지정합니다.
Name: "onUserCreated"
Enbaled: 토글을 "켜짐"으로 전환합니다.
Action Type: "만들기"를 선택합니다.
Provider(s): "이메일/비밀번호" 또는 사용 중인 인증 제공자를 선택합니다.
Select an Event Type: "기능"을 선택합니다.
Function: " +새 기능"을 선택합니다:
Function Name: "onUserCreated"
Function: 자리 표시자 텍스트를 다음 함수로 바꿉니다.
exports = function(authEvent) { const user = authEvent.user; const collection = context.services.get("mongodb-atlas").db("Item").collection("User"); const newDoc = { _id: user.id, email: user.data.email, // Useful for looking up user IDs by email later - assuming email/password auth is used team: "", // Used for tiered privileges isTeamAdmin: false, // Used for tiered privileges isGlobalAdmin: false, // Used for admin privileges subscribedTo: [], // Used for restricted feed }; return collection.insertOne(newDoc); };
joinTeam 함수 생성
이제 팀에 사용자를 추가하는 기능이 필요합니다. 이 기능은 시스템 인증 하에서 실행되며 사용자 지정 사용자 데이터에 기록됩니다. 사용자가 처음 인증에 성공할 때 사용자 맞춤 데이터가 생성되었으므로 업서트를 수행하지 않습니다.
함수를 만들려면 다음 단계를 따르세요.
Realm UI에 로그인한 다음 왼쪽 패널에서 Functions를 클릭합니다.
Create New Function 버튼을 클릭합니다.
다음 값을 지정합니다.
Name: "joinTeam"
Authentication: "System"
Function Editor 탭으로 전환하고 자리 표시자 텍스트를 다음 코드로 바꿉니다.
exports = async function(userId, teamName) { const collection = context.services.get("mongodb-atlas") .db("Item").collection("User"); const filter = { _id: userId }; const update = { $set: { team: teamName }}; const options = { upsert: false }; return collection.updateOne(filter, update, options); };
권한 정의
다음 권한은 두 가지 역할을 지정합니다/
teamAdmin은 사용자의 맞춤 데이터에
isTeamAdmin: true
가 있는 경우에만 적용됩니다. 이 경우 사용자는 문서의team
값이 사용자의team
값과 일치하는 모든 문서를 읽고 쓸 수 있습니다.teamMember는 모든 사용자에게 적용됩니다. 사용자는 자신의 문서를 작성하고 문서의
team
값이 사용자의team
값과 일치하는 모든 문서를 읽을 수 있습니다.
[ { "name": "admin", "apply_when": { "%%user.custom_data.isTeamAdmin": true }, "document_filter": { "read": { "team": "%%user.custom_data.team" }, "write": { "team": "%%user.custom_data.team" } }, "read": true, "write": true }, { "name": "user", "apply_when": {}, "document_filters": { "read": { "team": "%%user.custom_data.team" }, "write": { "owner_id": "%%user.id" } }, "read": true, "write": true } ]
참고
더 자세히 알아보기
이 전략을 확장하여 "GlobalAdmin" 역할을 지원할 수 있습니다. 글로벌 관리자는 어떤 팀에서든 만든 모든 문서에 대해 읽기 & 읽기 권한을 가졌을 것입니다.