비하인드 스토리: 멀티테넌트 앱에서 사용자 협업을 구현하는 방법
초대 및 역할 접근 관리 기능(예: Logto Cloud 협업)을 멀티테넌트 애플리케이션에서 구현하는 방법에 대한 실습과 인사이트를 제공합니다.
초대 및 역할 접근 관리 기능(예: Logto Cloud 협업)을 멀티테넌트 애플리케이션에서 구현하는 방법에 대한 실습과 인사이트를 제공합니다.
지난 주에 저희는 Logto Cloud에서 협업 기능을 도입했습니다. 이 소식을 놓치셨다면, 꼭 확인해 보세요! 이제 기존의 Logto 테넌트에 동료들을 초대하여 애플리케이션의 아이덴티티 시스템을 공동으로 유지 관리할 수 있습니다.
이번 기능 릴리스에서는 각 Logto 테넌트에 두 가지 역할을 추가했습니다:
저희는 자체 도구 사용을 고수하는 원칙에 따라, 사용자 협업 기능을 구축할 때 저희의 RBAC(역할 기반 접근 제어)와 조직 기능을 활용했습니다. RBAC에 익숙하지 않다면, 이전 게시물을 참고하여 시작해 보세요.
이번 블로그 게시물에서는 이 기능을 구현하기 위해 어떤 작업이 이루어졌는지, 멀티 조직 애플리케이션을 개발할 때 이러한 실천 방안이 어떻게 도움이 될 수 있는지 살펴보겠습니다.
각 Logto Cloud 테넌트는 시스템 내에서 독립적인 조직으로 기능하며, 저희 조직 기능이 이를 지원합니다. 테넌트 관리자와 협업자 역할을 도입하기 위해, 조직 템플릿에 두 가지 조직 역할을 만들었으며, 각각 특정 조직 권한 세트를 할당했습니다.


저희는 조직 기능에 초대 관련 관리 API 세트를 제공했습니다. 이 API를 통해 예를 들어:
POST /api/organization-invitations로 이메일 주소에 조직 초대를 생성하고 보낼 수 있습니다GET /api/organization-invitations & GET /api/organization-invitations/{id}로 초대를 조회할 수 있습니다PUT /api/organization-invitations/{id}/status로 초대 상태를 업데이트하여 초대를 수락하거나 거부할 수 있습니다자세한 내용은 전체 API 문서를 참조하세요.
초대가 이메일로 전송되므로, 이메일 커넥터가 적절히 구성되어 있는지 확인하세요. 이번 릴리스에서는 OrganizationInvitation이라는 새로운 이메일 템플릿 사용 유형을 도입하여, 초대 이메일 템플릿을 사용자 지정할 수 있습니다.

이 이메일 템플릿은 기본적으로 Logto 콘솔의 랜딩 페이지 링크({{link}}) 변수를 수락하며, 사용자는 이 링크를 통해 초대를 수락하고 Logto 테넌트에 참여할 수 있습니다. Logto Cloud의 랜딩 페이지 중 하나는 아래 스크린샷과 같습니다:

관리 API를 통해 초대 이메일을 보내는 방법에 대한 자세한 내용은 API 문서를 참조하세요.
위 설정을 통해 이메일로 초대를 보낼 수 있으며, 초대받은 사용자가 지정된 역할로 조직에 참여할 수 있습니다.
다른 조직 역할을 가진 사용자는 접근 토큰에 서로 다른 범위(권한)를 가집니다. 따라서 클라이언트 애플리케이션(Logto 콘솔)과 저희 백엔드 서비스 모두 이러한 범위를 확인하여 볼 수 있는 기능과 허용된 작업을 결정해야 합니다.
자, 이제 모든 것이 연결된 것 같고, 우리가 놓친 것이 있을까요?
접근 토큰 내 범위 업데이트를 관리하는 데는 다음이 포함됩니다:
Logto Cloud에서는 콘솔이 사용자의 범위를 SWR 요청을 사용해 적극적으로 체크하며, 사용자가 관리자로 승격될 때 자동으로 동의를 받습니다.
비슷한 기능을 RBAC로 구현하려면 범위 업데이트를 애플리케이션에 알리는 메커니즘(예: WebSocket 또는 서버 푸시 이벤트)이 필요하며, 이를 통해 재동의 또는 새로운 접근 토큰 발급을 조정할 수 있습니다. Logto는 향후 업데이트에서 이에 도움이 될 더 많은 웹 훅을 제공할 예정입니다.
Logto Cloud의 멀티 테넌시와 협업 기능은 저희 조직 기능을 활용합니다. 비슷한 멀티 테넌시 앱을 개발 중이라면, 유사한 접근 방식을 참고해 보세요.
이 블로그 게시물이 유익했기를 바랍니다. 질문이나 논의가 필요하다면, 저희 Discord 채널에 자유롭게 참여해 주세요.