本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
將自訂屬性傳送至 Amazon Cognito,並將其插入字符
Carlos Alessandro Ribeiro 和 Mauricio Mendoza,Amazon Web Services
Summary
將自訂屬性傳送至 Amazon Cognito 身分驗證程序可為應用程式提供額外的內容、啟用更精細的存取控制,並讓您更輕鬆地管理使用者設定檔和身分驗證要求。這些功能在各種應用程式和案例中都很有用,可協助您改善應用程式的整體安全性和功能。
此模式顯示當應用程式需要為存取字符或身分 (ID) 字符提供額外的內容時,如何將自訂屬性傳送至 Amazon Cognito 身分驗證程序。您可以使用 Node.js 做為後端應用程式。應用程式會從 Amazon Cognito 使用者集區驗證使用者,並傳遞產生字符所需的自訂屬性。您可以使用 Amazon Cognito AWS Lambda 的觸發條件來自訂身分驗證程序,而無需進行主要程式碼自訂或大量工作。
重要
此模式中的程式碼和範例不建議用於生產工作負載,因為它們僅用於示範用途。對於生產工作負載,用戶端需要額外的組態。使用此模式做為僅供試行或proof-of-concept參考。
先決條件和限制
先決條件
限制
此模式不適用於透過用戶端登入資料驗證流程進行應用程式整合。
產生金鑰前觸發條件只能新增或變更存取字符和身分字符的某些屬性。如需詳細資訊,請參閱 Amazon Cognito 文件中的產生字符前 Lambda 觸發程序。
架構
目標架構
下圖顯示此模式的目標架構。它也會顯示 Node.js 應用程式如何與後端搭配使用來更新資料庫。不過,後端資料庫更新超出此模式的範圍。

該圖顯示以下工作流程:
Node.js 應用程式會向 Amazon Cognito 使用者集區發出具有自訂屬性的存取字符。
Amazon Cognito 使用者集區會啟動預先金鑰產生 Lambda 函數,以自訂存取和 ID 權杖。
Node.js 應用程式會透過 Amazon API Gateway 進行 API 呼叫。
注意
此架構中顯示的其他架構元件僅為 ,且超出此模式的範圍。
自動化和擴展
您可以使用 、、HashiCorp Terraform
工具
AWS 服務
Amazon API Gateway 可協助您建立、發佈、維護、監控和保護任何規模的 REST、HTTP 和 WebSocket APIs。
Amazon Cognito 為 Web 和行動應用程式提供身分驗證、授權和使用者管理。
Amazon Elastic Container Service (Amazon ECS) 是快速、可擴展的容器管理服務,可協助您執行、停止和管理叢集上的容器。
AWS Lambda 是一項運算服務,可協助您執行程式碼,無需佈建或管理伺服器。它只會在需要時執行程式碼並自動擴展,因此您只需按使用的運算時間付費。
適用於 JavaScript 的 AWS SDK 提供 JavaScript JavaScript API AWS 服務。您可以使用它來建置 Node.js 或瀏覽器的程式庫或應用程式。
其他工具
最佳實務
我們建議您實作下列最佳實務:
秘密和敏感資料 – 請勿在應用程式中存放秘密或敏感資料。使用應用程式可以從中提取資料的外部系統,例如 AWS AppConfig、 AWS Secrets Manager或 AWS Systems Manager參數存放區。
標準化部署 – 使用 CI/CD 管道來部署您的應用程式。您可以使用 AWS CodeBuild和 等服務AWS CodePipeline。
權杖過期 – 設定存取權杖的簡短過期日期。
使用安全連線 – 用戶端應用程式與後端之間的所有通訊應使用 SSL/TLS 加密。使用 AWS Certificate Manager (ACM) 來產生和管理 SSL/TLS 憑證,並使用 Amazon CloudFront 或 Elastic Load Balancing 來處理 SSL/TLS 終止。
驗證使用者輸入 – 確保所有使用者輸入都經過驗證,以防止注入攻擊和其他安全漏洞。使用輸入驗證程式庫和服務,例如 Amazon API Gateway 和 AWS WAF,以防止常見的攻擊向量。
使用 IAM 角色 – 使用 AWS Identity and Access Management (IAM) 角色來控制對 AWS 資源的存取,並確保只有獲得授權的使用者才能存取。遵循最低權限原則,並確保每個使用者只有執行其角色所需的許可。
使用密碼政策 – 設定符合您安全需求的密碼政策,例如最短長度、複雜性和過期時間。使用 Secrets Manager 或 AWS Systems Manager 參數存放區安全地存放和管理密碼。
啟用多重要素驗證 (MFA) – 為所有使用者啟用 MFA,以提供額外的安全層,並降低未經授權的存取風險。使用 AWS IAM Identity Center或 Amazon Cognito 來啟用 MFA 和其他身分驗證方法。
安全地存放敏感資訊 – 使用 AWS Key Management Service (AWS KMS) 或其他加密服務安全地存放敏感資訊,例如密碼和存取權杖。
使用強式身分驗證方法 – 若要提高身分驗證程序的安全性,請使用強式身分驗證方法,例如生物識別驗證或多重要素驗證。
監控可疑活動 – 使用 AWS CloudTrail 和其他監控工具來監控可疑活動和潛在的安全威脅。設定異常活動的自動提醒,並使用 Amazon GuardDuty 或 AWS Security Hub 來偵測潛在威脅。
定期檢閱和更新安全政策 – 定期檢閱和更新安全政策和程序,以確保它們符合您不斷變化的安全需求和最佳實務。使用 AWS Config 來追蹤和稽核安全政策和程序的變更。
自動化註冊 – 請勿啟用 Amazon Cognito 使用者集區的自動註冊。如需詳細資訊,請參閱使用 Amazon Cognito 使用者集區降低使用者註冊詐騙和 SMS 輸出的風險
(AWS 部落格文章)。
如需其他最佳實務,請參閱 Amazon Cognito 文件中的 Amazon Cognito 使用者集區的安全最佳實務。 Amazon Cognito
史詩
| 任務 | 描述 | 所需的技能 |
|---|---|---|
建立使用者集區。 |
如需如何在 中設定使用者集區的詳細資訊和指示 AWS Management Console,請參閱使用者集區入門和將更多功能和安全性選項新增至您的使用者集區。 提示若要降低成本,請使用 Essentials 計劃或 Lite 計劃來測試此模式。如需詳細資訊,請參閱 Amazon Cognito 定價 | 應用程式開發人員、AWS DevOps |
將使用者新增至使用者集區。 | 輸入下列命令,在 Amazon Cognito 使用者集區中建立一個使用者:
| 應用程式開發人員、AWS DevOps |
將應用程式用戶端新增至使用者集區。 |
| AWS 系統管理員、AWS 管理員、AWS DevOps、應用程式開發人員 |
建立 Lambda 觸發程序以產生預先權杖。 | AWS DevOps,應用程式開發人員 | |
自訂使用者集區工作流程。 |
如需詳細資訊,請參閱 Amazon Cognito 文件中的使用 Lambda 觸發程序自訂使用者集區工作流程。 | AWS DevOps,應用程式開發人員 |
| 任務 | 描述 | 所需的技能 |
|---|---|---|
建立 Node.js 應用程式。 |
| 應用程式開發人員 |
實作身分驗證邏輯。 |
注意您可以建立自己的 TypeScript 檔案,或修改您的使用案例所需的範例。 | 應用程式開發人員 |
設定環境變數和組態檔案。 | 在終端機中,輸入下列命令來建立環境變數:
重要請勿硬式編碼秘密或公開您的登入資料。 | 應用程式開發人員 |
執行應用程式。 | 輸入下列命令來執行應用程式並確認其正常運作:
| 應用程式開發人員 |
確認自訂屬性已插入字符中。 | 使用 IDE 的偵錯功能來檢視存取和 ID 字符。確認已新增自訂屬性。如需範例字符,請參閱此模式的其他資訊一節。 | 應用程式開發人員 |
故障診斷
| 問題 | 解決方案 |
|---|---|
嘗試驗證使用者時無效的用戶端 ID | 當您使用用戶端 ID 搭配產生的用戶端秘密時,通常會發生此錯誤。您必須建立未連接秘密的用戶端 ID。如需詳細資訊,請參閱應用程式用戶端的應用程式特定設定。 |
相關資源
使用 Lambda 觸發來自訂使用者集區工作流程 (Amazon Cognito 文件)
權杖產生前 Lambda 觸發程序 (Amazon Cognito 文件)
CognitoIdentityProviderClient (適用於 JavaScript 的 AWS SDK 文件)
cognito-idp
(AWS CLI 文件)
其他資訊
範例 TypeScript 檔案
下列程式碼範例是 TypeScript 檔案,使用 AWS SDK 將自訂屬性傳送至 Amazon Cognito 來叫用身分驗證程序:
import * as AmazonCognitoIdentity from "amazon-cognito-identity-js"; const userPoolId: string = process.env.USER_POOL_ID ?? ''; const clientId: string = process.env.CLIENT_ID ?? ''; const poolData = { UserPoolId: userPoolId, ClientId: clientId }; const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData); export const loginWithCognitoSDK = function (userName: string, password: string) { const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({ Username: userName, Password: password, ClientMetadata: { customGroup: "MyCustomGroup", customApplicationData: "Custom data from a custom application" } }); const userData = { Username: userName, Pool: userPool }; const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData); // Authenticate the user using the authenticationDetails object cognitoUser.authenticateUser(authenticationDetails, { onSuccess: function (result: any) {}, onFailure: function (err: any) {}, }); } loginWithCognitoSDK(process.env.USERNAME ?? '', process.env.PASSWORD ?? '');
範例使用適用於 JavaScript 的 開發套件的 AuthenticationDetails模型來提供使用者名稱、密碼和 ClientMetadada。在 Amazon Cognito 中驗證之後,可以從存取和 ID 字符擷取用戶端中繼資料。
Lambda 函數範例
下列程式碼範例是連結至 Amazon Cognito 產生前字符的 Lambda 函數。它可協助您自訂 Amazon Cognito 使用的存取字符和 ID 字符。權杖會透過架構之間的整合傳遞。此範例包含名為 的自訂宣告屬性,customApplicationData以及名為 的自訂群組名稱MyCustomGroup:
export const handler = async(event, context, callback) => { event.response = { claimsOverrideDetails: { claimsToAddOrOverride: { customApplicationData: event.request.clientMetadata.customApplicationData }, groupOverrideDetails: { groupsToOverride: [event.request.clientMetadata.customGroup] } } }; callback(null, event); };
存取字符範例
您可以解碼存取權杖,以視覺化已新增的自訂屬性。以下是存取字符的範例:
{ "sub": "6daf331f-4451-48b4-abde-774579299204", "cognito:groups": [ "MyCustomGroup" ], "iss": "https://cognito-idp.<REGION>.amazonaws.com/<USERPOOL_ID>", "client_id": "<YOUR_CLIENT_ID>", "origin_jti": "acff7e91-09f9-4fde-8eec-38b0f8c47cdc", "event_id": "c5113a9c-1f01-435b-9b73-a5cd3e88514e", "token_use": "access", "scope": "aws.cognito.signin.user.admin", "auth_time": 1677979246, "exp": 1677982846, "iat": 1677979246, "jti": "5c9c2708-a871-4428-bd9b-18ad261bea90", "username": "<USER_NAME>" }
範例 ID 字符
您可以解碼存取權杖,以視覺化已新增的自訂屬性。以下是存取字符的範例:
{ "sub": "6daf331f-4451-48b4-abde-774579299204", "cognito:groups": [ "MyCustomGroup" ], "iss": "https://cognito-idp.<REGION>.amazonaws.com/<USERPOOL_ID>", "cognito:username": "<USER_NAME>", "origin_jti": "acff7e91-09f9-4fde-8eec-38b0f8c47cdc", "customApplicationData": "Custom data from a custom application", "aud": "<YOUR_CLIENT_ID>", "event_id": "c5113a9c-1f01-435b-9b73-a5cd3e88514e", "token_use": "id", "auth_time": 1677979246, "exp": 1677982846, "iat": 1677979246, "jti": "f7ca006b-f25b-44d2-a7a4-6e6423f4201f", "email": "<USER_EMAIL>" }