跳至主要內容

保護組織資源

除了將 API 作為資源的 保護你的 API 外,組織也可以作為資源,並以相同方式保護你的組織資源。在本文中,我們將專注於如何以類似方式保護你的組織資源。

步驟 1:從 OIDC 流程獲取組織 ID

Logto 擴展了標準的 OpenID Connect 協議,允許你的應用程式從使用者獲取組織資訊。有兩種方法可以做到這一點:

  • 如果你使用支援組織的 Logto SDK,可以將 urn:logto:scope:organizations 權限範圍新增到配置物件的 scopes 參數中。通常 SDK 會有一個枚舉來表示這個權限範圍,例如 Logto JS SDKs 中的 UserScope.Organizations
import { LogtoClient, UserScope } from '@logto/browser'; // 或 @logto/node, @logto/client

const logto = new LogtoClient({
// ...
scopes: [UserScope.Organizations],
});
  • 對於其他情況,你需要將 urn:logto:scope:organizations 權限範圍新增到 SDK 配置(或驗證請求)的 scope 參數中。

一旦使用者完成驗證流程,你可以從 idToken 獲取組織資訊:

// 使用 JavaScript 作為範例
const idToken = await logto.getIdTokenClaims();

console.log(idToken.organizations); // 組織 ID 的字串陣列

organizations 欄位(宣告)也會包含在 UserInfo 端點 的回應中。

可選:獲取組織角色

如果你尚未設定組織角色,請參閱此部分

要獲取當前使用者的所有組織角色:

  • 如果你使用支援組織的 Logto SDK,可以將 urn:logto:scope:organization_roles 權限範圍新增到配置物件的 scopes 參數中。通常 SDK 會有一個枚舉來表示這個權限範圍,例如 Logto JS SDKs 中的 UserScope.OrganizationRoles
  • 對於其他情況,你需要將 urn:logto:scope:organization_roles 權限範圍新增到 SDK 配置(或驗證請求)的 scope 參數中。

然後你可以從 idToken 獲取組織角色:

// 使用 JavaScript 作為範例
const idToken = await logto.getIdTokenClaims();

console.log(idToken.organization_roles); // 組織角色的字串陣列

陣列中的每個字串格式為 organization_id:role_id,例如 org_123:admin 表示使用者在 ID 為 org_123 的組織中擁有 admin 角色。

organization_roles 欄位(宣告)也會包含在 UserInfo 端點 的回應中。

步驟 2:獲取組織權杖

要在組織的上下文中執行操作,使用者需要獲得該組織的存取權杖(組織權杖)。組織權杖是一個包含組織 ID 和使用者在組織中權限(權限範圍)的 JWT 權杖。

新增參數到驗證請求

  • 如果你使用支援組織的 Logto SDK,可以將 urn:logto:scope:organizations 權限範圍新增到配置物件的 scopes 參數中,與 獲取當前使用者的組織 ID 相同。
    • 支援組織的 Logto SDK 會自動處理其餘的配置。
  • 對於其他情況,你需要將 offline_accessurn:logto:scope:organizations 權限範圍新增到 scope 參數中,並將 urn:logto:resource:organizations 資源新增到 SDK 配置(或驗證請求)的 resource 參數中。
    • 注意:offline_access 是獲取可用於獲取組織權杖的 refresh_token 所需的。
// 僅適用於其他情況。對於 Logto SDK,請參見上文。
const config = {
// ...
scope: 'openid offline_access urn:logto:scope:organizations',
resource: 'urn:logto:resource:organizations',
};
備註:

urn:logto:resource:organizations 資源是一個特殊資源,代表組織模板。

獲取組織權杖

Logto 擴展了標準的 refresh_token 授權類型,允許你的應用程式獲取組織權杖。

  • 如果你使用支援組織的 Logto SDK,可以調用 SDK 的 getOrganizationToken() 方法(或 getOrganizationTokenClaims() 方法)。
  • 對於其他情況,你需要使用以下參數調用權杖端點:
    • grant_type: refresh_token
    • client_id: 使用者用於驗證的應用程式 ID。
    • refresh_token: 你從驗證流程中獲得的 refresh_token
    • organization_id: 你想要獲取權杖的組織 ID。
    • scope(可選):你想要授予使用者在組織中的權限範圍。如果未指定,授權伺服器將嘗試授予與驗證流程相同的權限範圍。
const token = await logto.getOrganizationToken('<organization-id>');

回應將與 標準權杖端點 的格式相同,access_token 是 JWT 格式的組織權杖。

除了存取權杖的常規宣告外,組織權杖還包含以下宣告:

  • aud: 組織權杖的受眾是 urn:logto:organization:{organization_id}
  • scope: 使用者在組織中授予的權限範圍,以空格作為分隔符。

範例

一個好的範例勝過千言萬語。假設我們的組織模板有以下設置:

  • 權限:read:logswrite:logsread:userswrite:users
  • 角色:adminmember
    • admin 角色擁有所有權限。
    • member 角色擁有 read:logsread:users 權限。

使用者有以下設置:

  • 組織 ID:org_1org_2
  • 組織角色:org_1:adminorg_2:member

在 Logto SDK 配置(或驗證請求)中,我們正確設置了其他項目,並新增了以下權限範圍:

  • urn:logto:scope:organizations
  • openid
  • offline_access
  • read:logs
  • write:logs

現在,當使用者完成驗證流程時,我們可以從 idToken 獲取組織 ID:

// 使用 JavaScript 作為範例
const idToken = await logto.getIdTokenClaims();

console.log(idToken.organizations); // ['org_1', 'org_2']

如果我們想要獲取組織權杖:

// 使用 JavaScript 作為範例
const org1Token = await logto.getOrganizationTokenClaims('org_1');
const org2Token = await logto.getOrganizationTokenClaims('org_2');

console.log(org1Token.aud); // 'urn:logto:organization:org_1'
console.log(org1Token.scope); // 'read:logs write:logs'
console.log(org2Token.aud); // 'urn:logto:organization:org_2'
console.log(org2Token.scope); // 'read:logs'

const org3Token = await logto.getOrganizationTokenClaims('org_3'); // 錯誤:使用者不是該組織的成員

說明:

  • 對於 org_1,使用者擁有 admin 角色,因此組織權杖應具有所有可用的權限(權限範圍)。
  • 對於 org_2,使用者擁有 member 角色,因此組織權杖應具有 read:logsread:users 權限(權限範圍)。

由於我們在驗證流程中僅請求了 read:logswrite:logs 權限範圍,因此組織權杖已相應地「縮小範圍」,導致請求的權限範圍與可用權限範圍的交集。

為機器對機器應用程式獲取組織權杖

類似於為使用者獲取組織權杖,你也可以為機器對機器應用程式獲取組織權杖。唯一的區別是你需要使用 client_credentials 授權類型,而不是 refresh_token 授權類型。

要了解更多關於機器對機器應用程式的資訊,請參閱 機器對機器:使用 Logto 進行驗證

步驟 3:驗證組織權杖

一旦應用程式獲得組織權杖,它可以像常規存取權杖一樣使用該權杖,例如在 Authorization 標頭中以 Bearer {token} 格式調用 API。

在你的 API 中,驗證組織權杖的方式與 保護你的 API 相似。主要區別:

  • 與 API 資源的存取權杖不同,如果使用者不是組織的成員,則無法獲得組織權杖。
  • 組織權杖的受眾是 urn:logto:organization:{organization_id}
  • 對於某些權限(權限範圍),你需要通過以空格作為分隔符來檢查組織權杖的 scope 宣告。