建立多租戶 SaaS 應用程式:從設計到實現的完整指南
學習如何高效地建構一個具有穩健身份驗證、組織管理和基於角色的訪問控制功能的多租戶 SaaS 應用程式,僅需數小時。
應用程式如何如 Notion、Slack 或 Figma 這樣構建的?這些多租戶 SaaS 應用程式看似易用,但自己建造一個呢?那是另一個故事。
當我第一次想到構建這樣一個複雜的應用程式時,我腦子裡一片混亂:
- 用戶需要多種登錄選項(電子郵件,Google,GitHub)
- 每個用戶可以創建和屬於多個組織
- 每個組織內有不同的權限級別
- 企業組織要求自動加入特定電子郵件域名
- 敏感操作的 MFA 要求
- ...
"老闆,兩週後我們談談產品設計吧。我現在有點兒陷入困境。"
但當我實際上開始著手這項工作時,我發現事情並不像看起來那麼令人生畏。
我僅用不到 2 小時就建構了一個具備這些功能的系統!**
我將向你展示如何從頭開始設計和實施工程系統—你會驚訝於在 2025 年,不同於以往,它其實是如此簡單。
完整的源代碼在此文章的末尾提供。讓我們開始吧!
我們將從一個名為 DocuMind 的 AI 文檔 SaaS 產品開始。
DocuMind 是一種採用多租戶模型設計的 AI 文件產品,支持個人用戶、 小型企業和大型企業。
該平台提供強大的 AI 功能進行文檔管理,包括自動生成摘要、重點提取以及在組織內的智慧內容推薦。
SaaS 身份驗證和授權需要哪些功能?
首先,讓我們回顧必要的要求。你需要哪些功能?
多租戶架構
為實現多租戶架構,你需要一個名為 組織 的實體層。想象一下擁有一個用戶池,這些用戶可以訪問多個工作區。每個組織代表一個工作區,用戶在訪問不同工作區(組織)時保持單一身分,這基於其分配的角色。
這是在身份驗證提供商中廣泛使用的一個功能。身份管理系統中的組織對應於你的 SaaS 應用程式的工作區、項目或租戶。
成員資格
成員是一個臨時概念,用於指示一個身份在組織內的成員資格狀態。
例如,Sarah 使用她的電子郵 件 [email protected] 註冊你的應用程式。她可以屬於不同的工作區。如果 Sarah 屬於 工作區 A 但不屬於 工作區 B,那麼 Sarah 就被認為是 工作區 A 的成員,但不是 工作區 B 的成員。
角色和權限設計
在多租戶架構中,用戶需要具有特定權限的角色來訪問其租戶資源。
權限是詳細的存取控制,定義了具體的操作,例如 read: order
或 write: order
。它們決定了可以對特定資源執行的操作。
角色是分配給多租戶環境中成員的一組權限。
你需要定義這些角色和權限,然後分配角色給用戶,有時它可能包括自動化過程。例如:
- 加入組織的用戶自動獲得 成員 角色。
- 創建工作區的第一個用戶自動分配 管理員 角色。
註冊和登入流程
確保一個用戶友好且安全的註冊和身份驗證過程,包含基本的登入和註冊選項:
- 電子郵件和密碼登入:傳統的電子郵件和密碼登入方式。
- 無密碼登入:使用電子郵件驗證碼以簡單安全的方式登入。
- 帳號管理:用戶可以更新其電子郵件、密碼和其他詳細資料的帳戶中心。
- 社交登入: 提供如 Google 和 GitHub 這樣的選擇以快速登入。
- 多因素身份驗證 (MFA): 允許通過認證器應用程式,如 Duo 進行登入以增強安全性。
租戶創建和邀請
在一個多租戶 SaaS 應用中,一個關鍵的用戶流程是支持租戶創建和成員邀請。這一過程需要謹慎的計劃和執行,因為它在產品激活和增長中起著關鍵作用。
這裡有一些典型的用戶流程需要考慮:
用戶類型 | 入口點 |
---|---|
新帳戶 | 從登入和註冊頁面進入以創建一個新的租戶 |
現有帳戶 | 在產品內創建另一個租戶 |
現存帳戶獲得新租戶邀請 | 從登入和註冊頁面進入 |
現存帳戶獲得新租戶邀請 | 從邀請電子郵件進入 |
新帳戶獲得新租戶邀請 | 從登入和註冊頁面進入 |
新帳戶獲得新租戶邀請 | 從邀請電子郵件進入 |
這裡有一些幾乎在每個 SaaS 應用中都存在的常見情境。請以此作為靈感來源來啟發你的產品和設計團隊,也可以隨需要創造自己的流程。
技術架構和系統設計
一旦了解了所有的產品需求,讓我們進入到實施階段。
定義身份驗證策略
身份驗證看起來令人望而生畏。用戶需要:
- 電郵與密碼註冊/登入
- Google/Github 一鍵登入
- 忘記時重設密碼
- 企業客戶的團隊範圍登入
- ...
實現這些基本功能需要數週的開發。
但現在,我們不需要自己構建這些功能!
現代的身份驗證提供商(我這次選擇 Logto)已經為我們打包了這些功能。身份驗證流程非常簡單:
從數週的開發到 15 分鐘的設置,Logto 為我們處理所有複雜的流程!我們將在後面的實施部分中介紹整合步驟。現在我們可以專注於建構 DocuMind 的核心功能了!
建立多租戶架構
組織系統允許用戶創建和加入多個組織。讓我們了解一下核心關係:
在這個系統中,每個用戶可以屬於多個組織,每個組織可以有多個成員。
在多租戶應用中啟用訪問控制
基於角色的訪問控制(RBAC)對於確保多租戶 SaaS 應用程式裡的安全性和擴展性非常重要。
在多租戶應用程式中,權限和角色的設計通常是一致的,因為它源自產品設計。例如,在多個工作區中,通常有一個管理員角色和一個成員角色。作為一個身份驗證提供商,Logto 擁有以下組織層級基於角色的訪問控制設計:
- 統一的權限定義:權限在系統層級定義,並在所有組織間統一應用,確保可維護的一致權限管理
- 組織模板:通過組織模板預定義角色和權限的組合,簡化組織初始化
權限關係如下所示:
由於每個用戶在每個組織中需要自己的角色,因此角色與組織之間的關係必须反映每个用户分配的角色:
我們已經設計了組織系統和訪問控制系統,現在可以開始構建我們的產品!
技術棧
我選擇了一個對初學者友好的便攜棧:
- 前端:React(可以輕鬆切換到 Vue/Angular/Svelte)
- 後端:Express(簡單且直觀的 API)
為什麼區分前後端?因為它擁有清晰的架構,易於學習和簡單切換棧。作為身份驗證提供商,我使用 Logto 作為例子。
在以下指南中,這裡的模式適用於:任何前端、任何後端和任何身份驗證系統。
為你的應用添加基礎身份驗證流程
這是最簡單的一步。我們只需將 Logto 整合到我們的項目中。然後根據需求,可以在 Logto 控製台中配置用戶登入/註冊方法。
將 Logto 安裝到你的應用中
首先,登錄 Logto Cloud。如果你沒有帳戶,可以註冊一個免費的帳戶。為測試創建一個開發租戶。
在租戶控制台中,點擊左側的 “應用” 按鈕。然後選擇 React 開始構建我們的應用。
按照頁面上的指導操作,你可以在大約 5 分鐘內完成 Logto 的整合!
這是我的整合代碼:
這裡有一個有用的技巧:我們的登入頁面有登入和註冊按鈕。註冊按鈕直接導致 Logto 的註冊頁面。這可以通過 Logto 的第一個畫面功能來實現。它決定了用戶要首先看到驗證流程的哪一步。
當你的產品預期有許多新用戶時,你可以默認到註冊頁面。
點擊登入後,你將進入 Logto 登入頁面。在成功登入(或註冊)後,恭喜!你的應用程序有了第一個用戶(你)!
當你需要時,可以從 useLogto
鉤子調用 signOut
函數來登出用戶。
自定義登入和註冊方法
在 Logto 控制台中,點擊左側菜單的 "登入體驗"。然後點擊 "註冊和登入" 標籤。 在此頁面上,按照指示配置 Logto 的登入/註冊方法。
登入流程如下所示:
啟用多因素認證
在 Logto 中,啟用 MFA 很簡單。只需點擊 Logto 控制台中的 "多因素身份驗證" 按鈕。然後在多因素身份驗證頁面上啟用它。
MFA 流程將如下所示:
一切都如此簡單!短短幾分鐘內,我們已經設置了一個複雜的用戶身份驗證系統!
添加多租戶組織體驗
現在,我們有了我們的第一個用戶!然而,這個用戶尚未屬於任何組織,也未創建任何組織。
Logto 提供對多租戶的內建支持。你可以在 Logto 中創建任意數量的組織。每個組織可以有多個成員。
每個用戶都可以從 Logto 獲取其組織信息。這使得多租戶支持成為可能。
獲取用戶的組織信息
要從 Logto 獲得用戶的組織信息,請按照以下兩個步驟進行:
在 Logto 配置中聲明組織信息訪問。這在設置適當的 scopes
和 resources
來完成。
使用 Logto 的 fetchUserInfo
方法來獲取用戶信息,包括組織數據。
完成這些步驟後,你需要登出並重新登入。這是必要的,因為我們修改了請求的權限範圍和資源。
現在,你還沒有創建任何組織,並且用戶也沒有加入任何組織。儀表板將顯示 "你還沒有任何組織"。
接下來,我們將為用戶創建一個組織並將其添加到其中。
感謝 Logto,我們不需要構建複雑的組織關係。我們只需要在 Logto中創建一個組織並將用戶添加到其中。Logto將為我們處理所有的複雜性。有兩種方法來創建組織:
- 通過 Logto 控制台手動創建組織
- 使用 Logto 管理 API 創建組織,特別是在設計讓用戶可以創建自己組織(工作區)流程時。
在 Logto 控制台中創建組織
點擊左側 Logto 控制台的“組織”菜單按鈕。創建一個組織。
現在你有了你的第一個組織。
接下來,讓我們將用戶添加到這個組織。
進入組織詳細信息頁面。切換至成員標籤。點擊“+ 添加成員”按鈕。從左側列表中選擇你的登入用戶。點擊右下角的“添加成員”按鈕。現在你已經成功將用戶添加到這個組織中。
刷新你的應用程式頁面。你會看到用戶現在已經屬於一個組織!
實現自助式組織創建體驗
在控制台創建組織是不夠的。你的 SaaS 應用需要一個流程讓終端用戶可以輕鬆創建和管理自己的工作區。要實現此功能,使用 Logto 管理 API。
如需指導,請查看 Interact with Management API 文件以設置與 Logto 的 API 通信。
了解組織身份驗證互動流程
讓我們以組織創建流程為例。以下是組織創建流程的工作原理:
此流程有兩個關鍵身份驗證要求:
- 保護後端服務 API:
- 前端訪問我們的後端服務 API 需要身份驗證
- API 端點通過驗證用戶的 Logto 訪問令牌進行保護
- 確保只有通過身份驗證的用戶可以訪問我們的服務
- 訪問 Logto 管理 API:
- 後端服務需要安全地調用 Logto 管理 API
- 按照Interact with Management API指引進行設置
- 使用機器對機器身份驗證來獲取訪問憑據
保護你的後端 API
首先,讓我們在後端服務中創建一個用於創建組織的 API 端點。
我們的後端服務 API 只允許經過身份驗證的用戶。我們需要使用 Logto 來保護我們的 API。我們還需要知道當前用戶的信息(比如用戶 ID)。
在 Logto 的概念中(以及 OAuth 2.0),我們的後端服務充當資源伺服器。用戶通過前端訪問 DocuMind 資源伺服器獲得 Logto 訪問令牌。資源伺服器驗證此令牌。如果有效,它會返回請求的資源。
讓我們創建一個 API 資源來表示我們的後端服務。
進入 Logto 控制台。
- 點擊右側的 "API 資源" 按鈕。
- 點擊 "創建 API 資源"。在彈出窗口中選擇 Express。
- 填寫 "DocuMind API" 作為 API 名稱。使用 "https://api.documind.com" 作為 API 識別符。
- 點擊創建。
請不要擔心這個 API 識別符 URL。它只是用於 Logto 中 API 的唯一識別符,與實際的後端服務 URL 無關。
你會看到使用 API 資源的教程。你可以按照該教程或下面的步驟進行。
創建一個 requireAuth 中介軟體來保護我們的 POST /organizations 端點。
要使用此中介程式,我們需要這些環境變量:
- LOGTO_JWKS_URL
- LOGTO_ISSUER
從你的 Logto 租戶的 OpenID 配置端點獲取這些變量。訪問 https://<your-tenant-id>.logto.app/oidc/.well-known/openid-configuration
。你可以在返回的 JSON 中找到所需的信息:
現在,我們在 POST /organizations 端點中使用 requireAuth 混入。
這樣就保護了我們的 POST /organizations 端點。只有持有有效 Logto 訪問令牌的用戶才能訪問它。
現在,我們可以從 Logto 獲得令牌。用戶可以透過這個令牌通過我們的後端服務創建組織。中介工具還為我們提供用戶 ID,這有助於添加用戶到組織中。
在前端代碼中,將此 API 資源宣告在 Logto 配置中。將其識別符號添加到數據數組中。
如前所述,在我們更新 Logto 配置後,用戶需要重新登入。
在儀表板中,獲取用於創建組織的 Logto 訪問令牌。使用此令牌來訪問我們的後端服務 API。
現在,我們可以正常訪問 DocuMind 後端服務 API。
調用 Logto 管理 API
讓我們使用 Logto 管理 API 實現組織創建。
就像前端發送請求給後端服務一樣,後端服務發送請求給 Logto 需要訪問令牌。
在 Logto 中,我們使用機器對機器身份驗證獲取訪問令牌。詳情請參閱 Interact with Management API。
進入 Logto 控制台中的應用程式頁面。創建一個機器對機器應用程式。分配 "Logto 管理 API 访问" 角色。複製 Token 端點、應用 ID 和應用程式秘密。接下來,我們將使用這些變量來獲取訪問令牌。
現在,我們可以通過這個 M2M 應用程式獲得 Logto 管理 API 的訪問令牌。
用訪問令牌調用 Logto 管理 API。
我們將使用這些管理 API:
POST /api/organizations
: 創建組織 (詳見:創建組織 API 參考)POST /api/organizations/{id}/users
: 將用戶添加到組織 (詳見:將用戶添加到組織 API 參考)
我們已經實現了透過 Logto 管理 API 的組織創建。我們還可以將用戶添加到組織中。
讓我們在儀表板中測試此功能。
然後點擊“創建组织”
創建成功!
下一步將是邀請用戶加入組織。我們的教學還沒有實現這個功能。你已經了解如何使用管理 API。你可以參考這篇 租戶的創建和邀請 作為產品設計參考,並根據這篇博客文章輕鬆實現該功能: 如何在多租戶應用中實施用戶協作。
實施對多租戶應用的存取控制
現在讓我們進入組織存取控制。
我們想要達成:
- 用戶只能訪問他們自己的組織的資源:這可以透過 Logto 的
organization token
實現 - 用戶在組織內擁有特定角色(包含不同的權限)來執行授權操作:這可以通過 Logto 的組織模板功能實現
讓我們看看如何實現這些功能。
使用 Logto 組織令牌
類似於我們前面提到的 Logto 訪問令牌,Logto 簽發的訪問令牌對應於特定資源,用戶使用此令牌訪問受保護的資源在後端服務中。相應地,Logto 簽發的組織令牌對應於特定的組織,用戶使用此令牌訪問受保護的組織資源在後端服務中。
在前端應用中,我們可以使用 Logto 的 getOrganizationToken
方法來獲取特定組織的令牌以供訪問。
在此,organizationId
是用戶所屬的組織的 id。
在使用 getOrganization
或任何組織功能前,我們需要確保 urn:logto:scope:organizations
範圍和 urn:logto:resource:organization
資源已包含在 Logto 配置中。因為我們先前已經聲明了這些,我們此處將不再重複。
在我們的組織頁面上,我們使用組織令牌來獲取組織內的文件。
這個實施中有兩個重要的要點:
- 如果傳給
getOrganizationToken
的organizationId
不是當前用戶所屬的組織 ID,這個方法無法獲取令牌,從而確保用戶只能訪問他自己的組織。 - 在請求組織資源時,我們使用組織令牌而不是訪問令牌,因為對於屬於組織的資源,我們要使用組織許可控制而不是用戶許可控制(在稍後實現
GET /documents
API 時,你會更好地理解这一点)。
接下來,我們在後端服務中創建一個 GET /documents
API。類似於如何使用 API 資源保護 POST /organizations
API,我們使用組織專用資源指標來保護 GET /documents
API。
首先,讓我們創建一個 requireOrganizationAccess
中介軟體來保護組織資源。
然後,我們使用 requireOrganizationAccess
中介軟體來保護 GET /documents
API。
這樣,我們已經實現了使用組織令牌來訪問組織資源。在後端服務中,你可以根據組織 id 從數據庫中檢索相應的資源。
某些軟件需要不同組織之間的数据隔離。如需進一步討論和實施,可以參考博客文章:使用 PostgreSQL 實現多租戶:通過一個簡單的實際示例學習。
實現組織級別基於角色的訪問控制設計
我們已經實現了使用組織令牌來訪問組織資源。接下來,我們將實現使用 RBAC 來控制組織內用戶的權限。
假設 DocuMind 有兩個角色:管理員和協作者。
管理員可以創建和訪問文件,而協作者只能訪問文件。
因此,我們的組織需要這兩個角色:管理員和協作者。
管理員擁有 read:documents
和 create:documents
權限,而協作者只有 read:documents
權限。
- Admin
read:documents
create:documents
- Collaborator
read:documents
這就是 Logto 的組織模板功能的優勢所在。
組織模 板是為每個組織的訪問控制模型提供的藍圖:它定義了適用於所有組織的角色和權限。
為什麼要使用組織模板?
因為可擴展性是 SaaS 產品最重要的要求之一。換言之,對一個客戶有效的東西對所有客戶也應有效。
讓我們進入 Logto 控制台 > 組織模板 > 組織權限,創建兩個權限:read:documents
和 create:documents
。
然後進入組織角色標籤來創建两個用戶角色:“管理員”和“協作者”,並為这些角色分配相應的權限。
這樣就為每個組織創建了一個 RBAC 許可模型。
接下來,我們進入我們的組織详细信息页面,為我们的成員分配合适的角色。
现在我们的组织用户有角色了! 你可以通过 Logto 管理 API 实现这些步骤:
现在我们可以通过检查它们的权限来实现用户权限控制。
我们的代码中,我们需要使用户的组织令牌携带权限信息,然后在后端验证这些权限。
在前端代码的 Logto 配置中,我们需要声明用户在组织内请求的权限。让我们添加 read:documents
和 create:documents
权限到 scopes
中。
如往常一樣,登錄重新使用户以使這些配置生效。
然後在後端的 requireOrganizationAccess
中介軟 體中,我們添加檢查用戶許可的驗證。
然後創建一個 POST /documents API,並使用帶有 requiredScopes 配置的 requireOrganizationAccess
中介軟體來保護此 API 和前面的 GET /documents
API。
這樣,我們通過檢查用戶許可来實現了用戶許可控制。
在前端,你可以通過解碼组织标记获得用户权限信息,或者调用 Logto 的 getOrganizationTokenClaims
方法。
通过检查声明中的范围,控制基于用户权限的页面元素。
添加更多多租戶應用功能
到目前為止,我們已經實現了多租戶 SaaS 系統中的基本用戶和組織功能!然而,還有一些我們沒有覆蓋的功能,比如為每個組織自定义登陆頁面品牌、自动將特定域名的電子郵件用戶添加到某些組織,以及集成企业级 SSO 功能。
这些都是开箱即用的功能,你可以在 Logto 文档中找到更多关于这些功能的信息。
總結
還記得一開始多麼壓倒一切嗎?用戶、組織、許可、企業功能......看上去似乎是一座無盡的山峰。
但看看我們完成了什麼:
- 一個完整的身份驗證系統,具有多种登入選項和 MFA 支持
- 一個靈活的組織系統,支持多個成員資格
- 組織內基於角色的存取控制
最好的部分是什麼?我們不必重新發明輪子。通過利用像 Logto 這樣的現代工具,我們將月份的開發轉化為幾小時的工作。
本教程的完整代碼位於:多租戶 SaaS 示例。
這是 2025 年現代開發的力量——我們可以專注於構建獨特產品功能,而不是與基礎設施作鬥爭。現在輪到你建造一些了不起的東西啦!
探索所有的 Logto 功能,從 Logto Cloud 到 Logto OSS,都在 Logto 網站 上,或者今天就注册 Logto cloud。