建立自訂權杖宣告 (claims) 腳本
若要新增自訂宣告 (claims)到存取權杖 (Access token),你需要提供一個回傳包含這些宣告 (claims) 的物件的腳本。該腳本應以 JavaScript 函式撰寫,並回傳一個包含自訂宣告 (claims) 的物件。
-
前往 主控台 > 自訂 JWT。
-
你可以針對兩種不同類型的存取權杖 (Access token) 自訂其權杖宣告 (claims):
- 使用者存取權杖 (User access token):發給終端使用者的存取權杖。例如 Web 應用程式或行動應用程式。
- 機器對機器存取權杖 (Machine-to-Machine access token):發給服務或應用程式的存取權杖。例如機器對機器應用程式。
不同類型的存取權杖 (Access token) 可能有不同的權杖內容 (payload) 上下文。你可以分別自訂每種存取權杖的宣告 (claims)。
選擇你想自訂權杖宣告 (claims) 的存取權杖類型,然後點擊 新增自訂宣告 (Add custom claims) 按鈕來建立新腳本。
自訂權杖宣告 (claims) 功能僅提供給:
- Logto OSS 使用者
- Logto Cloud 開發環境租戶
- Logto Cloud 付費租戶的生產環境(包含 Pro 租戶與 Enterprise 租戶)
實作 getCustomJwtClaims() 函式
在 自訂 JWT 詳細頁面,你可以找到腳本編輯器來撰寫你的自訂權杖宣告 (claims) 腳本。該腳本應為一個回傳自訂宣告 (claims) 物件的 JavaScript 函式。
步驟 1:編輯腳本
使用左側的程式碼編輯器來修改腳本。預設會提供一個回傳空物件的 getCustomJwtClaims,你可以從這裡開始,修改函式以回傳你自訂的宣告 (claims) 物件。
const getCustomJwtClaims = async ({ token, context, environmentVariables }) => {
return {};
};
此編輯器使用 JavaScript 語言伺服器,提供基本語法高亮、程式碼補全與錯誤檢查。輸入參數皆有良好型別與 jsDoc 文件說明。你可以利用編輯器的 IntelliSense 正確存取輸入物件的屬性。詳細參數定義可於頁面右側查看。
此函式將作為模組匯出。請務必保持函式名稱為 getCustomJwtClaims,以確保模組正確匯出該函式。
步驟 2:輸入參數
getCustomJwtClaims 函式接受一個物件作為輸入參數。該輸入物件包含以下屬性:
token
權杖內容 (payload) 物件。此物件包含原始權杖宣告 (claims) 與你可能需要在腳本中存取的中繼資料。
你可以在頁面右側找到權杖內容 (payload) 物件與使用者資料物件的詳細型別定義。編輯器的 IntelliSense 也會協助你正確存取這些屬性。
- 使用者存取權杖資料物件
屬性 (Property) 說明 (Description) 型別 (Type) jtiJWT 唯一識別碼 stringaud權杖的受眾 (Audience) stringscope權杖的權限範圍 (Scopes) stringclientId權杖的用戶端 ID stringaccountId權杖的使用者 ID stringexpiresWithSession權杖是否隨會話到期 booleangrantId權杖的當前驗證 (Authentication) 授權 ID stringgty權杖的授權類型 stringkind權杖類型 AccessToken - 機器對機器存取權杖資料物件
屬性 (Property) 說明 (Description) 型別 (Type) jtiJWT 唯一識別碼 stringaud權杖的受眾 (Audience) stringscope權杖的權限範圍 (Scopes) stringclientId權杖的用戶端 ID stringkind權杖類型 ClientCredentials
context(僅適用於使用者存取權杖)
context 物件包含與當前授權 (Authorization) 流程相關的使用者資料與授權資料。
-
使用者資料物件 對於使用者存取權杖,Logto 會提供額外的使用者資料 context 供你存取。該物件包含所有使用者個人資料與組織 (Organization) 成員資料,方便你設置自訂宣告 (claims)。詳情請參閱 使用者 與 組織。
-
授權資料物件 對於透過模擬 (Impersonation) 權杖交換取得的使用者存取權杖,Logto 會提供額外的授權資料 context。該物件包含來自主體 (Subject) 權杖的自訂 context。詳情請參閱 使用者模擬 (User impersonation)。
-
使用者互動資料物件 對於特定使用者存取權杖,有時你需要存取當前授權 (Authorization) 會話的使用者互動細節。例如,你可能需要取得使用者登入時所用的企業級單一登入 (Enterprise SSO) 身分。此物件包含最近一次使用者提交的互動資料,包括:
屬性 (Property) 說明 (Description) 型別 (Type) interactionEvent當前使用者互動事件 SignIn或RegisteruserId當前使用者互動的使用者 ID stringverificationRecords使用者於互動過程中提交的驗證紀錄清單,用於識別與驗證身分 VerificationRecord[]驗證紀錄型別:
// VerificationType.Password
{
id: string;
type: 'Password';
identifier: {
type: 'username' | 'email' | 'phone' | 'userId';
value: string;
}
verified: boolean;
}// VerificationType.EmailVerificationCode
{
id: string;
templateType: 'SignIn' | 'Register' | 'ForgotPassword' | 'Generic';
verified: boolean;
type: 'EmailVerificationCode';
identifier: {
type: 'email';
value: string;
}
}// VerificationType.PhoneVerificationCode
{
id: string;
templateType: 'SignIn' | 'Register' | 'ForgotPassword' | 'Generic';
verified: boolean;
type: 'PhoneVerificationCode';
identifier: {
type: 'phone';
value: string;
}
}// VerificationType.Social
{
id: string;
type: 'Social';
connectorId: string;
socialUserInfo?: {
id: string;
email?: string | undefined;
phone?: string | undefined;
name?: string | undefined;
avatar?: string | undefined;
rawData?: Record<string, unknown> | undefined;
} | undefined;
}// VerificationType.EnterpriseSso
{
id: string;
type: 'EnterpriseSso';
connectorId: string;
enterpriseUserInfo?: {
id: string;
email?: string | undefined;
phone?: string | undefined;
name?: string | undefined;
avatar?: string | undefined;
[key: string]?: unknown;
} | undefined;
issuer?: string | undefined;
}// VerificationType.Totp (MFA)
{
id: string;
type: 'Totp';
userId: string;
verified: boolean;
}// VerificationType.WebAuthn (MFA)
{
id: string;
type: 'WebAuthn';
userId: string;
verified: boolean;
}// VerificationType.BackupCode (MFA)
{
id: string;
type: "BackupCode";
userId: string;
code?: string | undefined;
}// VerificationType.OneTimeToken
{
id: string;
type: "OneTimeToken";
verified: boolean;
identifier: {
type: "email";
value: string;
};
oneTimeTokenContext?: {
jitOrganizationIds?: string[] | undefined;
} | undefined;
}備註:使用者互動資料物件中可能包含多筆驗證紀錄,特別是當使用者經歷多次登入或註冊流程時。
例如,使用者先以
Social驗證紀錄登入,再透過EmailVerificationCode綁定新電子郵件,最後以Totp驗證紀錄驗證 MFA 狀態。在這種情況下,你可能需要在腳本中分別處理所有驗證紀錄。每種驗證紀錄類型在使用者互動資料物件中僅會出現一次。
environmentVariables
使用右側的 設定環境變數 (Set environment variables) 區塊來為你的腳本設置環境變數。你可以利用這些變數儲存敏感資訊或設定資料,避免在腳本中硬編碼。例如 API 金鑰、密鑰或 URL。
你在此設置的所有環境變數都可於腳本中存取。請透過輸入參數中的 environmentVariables 物件來取得這些變數。
api
api 物件提供一組實用函式,讓你在腳本中對權杖發放流程進行額外存取控制。api 物件包含以下函式:
api.denyAccess(message?: string): void
api.denyAccess() 函式允許你以自訂訊息拒絕權杖發放流程。你可以利用此函式對權杖發放流程施加額外存取驗證。
步驟 3:擷取外部資料
你可以在腳本中使用 Node 內建的 fetch 函式來擷取外部資料。fetch 是一個基於 Promise 的函式,允許你向外部 API 發送 HTTP 請求。
const getCustomJwtClaims = async ({ environmentVariables }) => {
const response = await fetch('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${environmentVariables.API_KEY}`,
},
});
const data = await response.json();
return {
data,
};
};
請注意,任何外部資料擷取都可能為權杖發放流程帶來延遲。請確保外部 API 可靠且速度足以符合你的需求。
此外:
- 請妥善處理腳本中的錯誤與逾時,避免權杖發放流程被阻塞。
- 使用適當的授權標頭,保護你的外部 API 不被未授權存取。
步驟 4:測試腳本
請務必在儲存前測試你的腳本。點擊頁面右側的 測試 context (Test context) 分頁,修改測試用的權杖內容 (payload) 與使用者資料 context。
點擊編輯器右上角的 執行測試 (Run test),即可以測試資料執行腳本。腳本的輸出結果將顯示於 測試結果 (Test Result) 抽屜中。
測試結果即為 getCustomJwtClaims 函式以你設定的測試資料執行後的輸出(即時序圖第 3 步取得的「額外權杖宣告 (extra token claims)」)。實際權杖內容 (payload) 與使用者資料 context 會因發放流程而異。
點擊 建立 (Create) 按鈕以儲存腳本。自訂權杖宣告 (claims) 腳本將被儲存並應用於存取權杖發放流程。