將自訂屬性傳送至 Amazon Cognito,並將其插入字符 - AWS 方案指引

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

將自訂屬性傳送至 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參考。

先決條件和限制

先決條件

  • 作用中 AWS 帳戶

  • 建立和管理 Amazon Cognito 使用者集區和 AWS Lambda 函數的許可

  • AWS Command Line Interface (AWS CLI),已安裝設定

  • 支援 Node.js 的整合式開發環境 (IDE)

  • Node.js 第 18 版或更新版本,已安裝

  • npm 第 8 版或更新版本,已安裝

  • TypeScript,已安裝

限制

  • 此模式不適用於透過用戶端登入資料驗證流程進行應用程式整合。

  • 產生金鑰前觸發條件只能新增或變更存取字符和身分字符的某些屬性。如需詳細資訊,請參閱 Amazon Cognito 文件中的產生字符前 Lambda 觸發程序。

架構

目標架構

下圖顯示此模式的目標架構。它也會顯示 Node.js 應用程式如何與後端搭配使用來更新資料庫。不過,後端資料庫更新超出此模式的範圍。

Node.js 應用程式向 Amazon Cognito 使用者集區發出具有自訂屬性的存取字符。

該圖顯示以下工作流程:

  1. Node.js 應用程式會向 Amazon Cognito 使用者集區發出具有自訂屬性的存取字符。

  2. Amazon Cognito 使用者集區會啟動預先金鑰產生 Lambda 函數,以自訂存取和 ID 權杖。

  3. Node.js 應用程式會透過 Amazon API Gateway 進行 API 呼叫。

注意

此架構中顯示的其他架構元件僅為 ,且超出此模式的範圍。

自動化和擴展

您可以使用 、、HashiCorp Terraform 或任何支援的基礎設施即程式碼 (IaC) 工具AWS CloudFormation,自動佈建 Amazon Cognito 使用者集區、 AWS Lambda 函數AWS Cloud Development Kit (AWS CDK)、資料庫執行個體和其他資源。如果您想要擴展部署,請使用持續整合和持續交付 (CI/CD) 管道,這有助於防止與手動部署相關的錯誤。

工具

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 或瀏覽器的程式庫或應用程式。

其他工具

  • Node.js 是一種事件驅動的 JavaScript 執行期環境,專為建置可擴展的網路應用程式而設計。

  • npm 是在 Node.js 環境中執行的軟體登錄檔,用於共用或借用套件和管理私有套件的部署。

最佳實務

我們建議您實作下列最佳實務:

  • 秘密和敏感資料 – 請勿在應用程式中存放秘密或敏感資料。使用應用程式可以從中提取資料的外部系統,例如 AWS AppConfigAWS Secrets ManagerAWS Systems Manager參數存放區

  • 標準化部署 – 使用 CI/CD 管道來部署您的應用程式。您可以使用 AWS CodeBuild和 等服務AWS CodePipeline

  • 權杖過期 – 設定存取權杖的簡短過期日期。

  • 使用安全連線 – 用戶端應用程式與後端之間的所有通訊應使用 SSL/TLS 加密。使用 AWS Certificate Manager (ACM) 來產生和管理 SSL/TLS 憑證,並使用 Amazon CloudFrontElastic 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 GuardDutyAWS Security Hub 來偵測潛在威脅。

  • 定期檢閱和更新安全政策 – 定期檢閱和更新安全政策和程序,以確保它們符合您不斷變化的安全需求和最佳實務。使用 AWS Config 來追蹤和稽核安全政策和程序的變更。

  • 自動化註冊 – 請勿啟用 Amazon Cognito 使用者集區的自動註冊。如需詳細資訊,請參閱使用 Amazon Cognito 使用者集區降低使用者註冊詐騙和 SMS 輸出的風險 (AWS 部落格文章)。

如需其他最佳實務,請參閱 Amazon Cognito 文件中的 Amazon Cognito 使用者集區的安全最佳實務。 Amazon Cognito

史詩

任務描述所需的技能

建立使用者集區。

  1. 在 CLI 終端機中,輸入下列命令來建立 Amazon Cognito 使用者集區:

    aws cognito-idp create-user-pool \ --pool-name <MyUserPool>
  2. 輸入下列命令來建立用戶端 ID 和秘密,以便與適用於 JavaScript 的 SDK 搭配使用:

    aws cognito-idp create-user-pool-client \ --user-pool-id <UserPoolID> \ --client-name <MyNewClient> \ --no-generate-secret \ --explicit-auth-flows "USER_PASSWORD_AUTH" "ADMIN_NO_SRP_AUTH"

如需如何在 中設定使用者集區的詳細資訊和指示 AWS Management Console,請參閱使用者集區入門將更多功能和安全性選項新增至您的使用者集區

提示

若要降低成本,請使用 Essentials 計劃或 Lite 計劃來測試此模式。如需詳細資訊,請參閱 Amazon Cognito 定價

應用程式開發人員、AWS DevOps

將使用者新增至使用者集區。

輸入下列命令,在 Amazon Cognito 使用者集區中建立一個使用者:

aws cognito-idp sign-up \ --client-id <ClientID> \ --username <jane@example.com> \ --password <PASSWORD> \ --user-attributes Name="email",Value="<jane@example.com>" Name="name",Value="<Jane>"
應用程式開發人員、AWS DevOps

將應用程式用戶端新增至使用者集區。

  1. 導覽至 Amazon Cognito 主控台

  2. 選擇 User pools (使用者集區)。

  3. 選擇您先前建立的使用者集區。

  4. 定義應用程式下,選擇最適合您要為其建立身分驗證和授權服務之應用程式案例的應用程式類型

  5. 為您的應用程式命名中,輸入描述性名稱或繼續預設名稱。

  6. 新增傳回 URL 下,輸入使用者完成身分驗證後應用程式的重新導向路徑。

  7. 選擇建立您的應用程式。您可以在建立應用程式用戶端後設定進階選項。

AWS 系統管理員、AWS 管理員、AWS DevOps、應用程式開發人員

建立 Lambda 觸發程序以產生預先權杖。

  1. 開啟 Lambda 主控台中的 函數頁面

  2. 選擇建立函數

  3. 選取從頭開始撰寫

  4. 基本資訊窗格中, forFunction 名稱,輸入 myPreTokenGenerationLambdaFunction

  5. ForRuntime,選擇 Node.js 22

  6. Leavearchitectureset tox86_64

  7. 選擇 Create function (建立函數)

  8. 程式碼索引標籤的程式碼來源下,從此模式的其他資源區段輸入範例 Lambda 函數。此 Lambda 函數會將自訂屬性注入 ID 字符和存取字符。

AWS DevOps,應用程式開發人員

自訂使用者集區工作流程。

  1. 導覽至 Amazon Cognito 主控台

  2. 選擇 User pools (使用者集區)。

  3. 選擇您先前建立的使用者集區。

  4. 在左側導覽窗格的身分驗證下,選擇延伸

  5. 選擇新增 Lambda 觸發程序。

  6. 新增或編輯產生權杖前觸發程序

  7. 針對觸發類型,選擇身分驗證

  8. 身分驗證下,選擇權杖產生前觸發條件。

  9. 對於指派 Lambda 函數,選擇 myPreTokenGenerationLambdaFunction

  10. 選擇新增 Lambda 觸發程序。

  11. 選擇 aTrigger 事件版本基本功能 + 使用者身分的存取權杖自訂基本功能 + 使用者和機器身分的存取權杖自訂。此設定會更新 Amazon Cognito 傳送至您函數的請求參數,以包含用於存取權杖自訂的欄位。

如需詳細資訊,請參閱 Amazon Cognito 文件中的使用 Lambda 觸發程序自訂使用者集區工作流程

AWS DevOps,應用程式開發人員
任務描述所需的技能

建立 Node.js 應用程式。

  1. 在終端機中,輸入下列命令:

    mkdir my-app cd my-app npm init -y npm install --save-dev typescript npm i --save-dev @types/node npm i amazon-cognito-identity-js npx tsc --init mkdir src touch src/index.ts
  2. 修改 package.json檔案以包含 TypeScript 編譯指令碼:

    "scripts": { "start": "node src/index.js", "build": "tsc" },
應用程式開發人員

實作身分驗證邏輯。

  1. 開啟 index.ts 檔案。

  2. 貼上此模式的其他資源區段中提供的範例 Typescript。

  3. 儲存並關閉 index.ts 檔案。

注意

您可以建立自己的 TypeScript 檔案,或修改您的使用案例所需的範例。

應用程式開發人員

設定環境變數和組態檔案。

在終端機中,輸入下列命令來建立環境變數:

export USERNAME="<COGNITO_USER_NAME>" export PASSWORD="<COGNITO_USER_PASSWORD>" export USER_POOL_ID="<COGNITO_USER_ID>" export CLIENT_ID="<COGNITO_CLIENT_ID>"
重要

請勿硬式編碼秘密或公開您的登入資料。

應用程式開發人員

執行應用程式。

輸入下列命令來執行應用程式並確認其正常運作:

npm run build npm start
應用程式開發人員

確認自訂屬性已插入字符中。

使用 IDE 的偵錯功能來檢視存取和 ID 字符。確認已新增自訂屬性。如需範例字符,請參閱此模式的其他資訊一節。

應用程式開發人員

故障診斷

問題解決方案

嘗試驗證使用者時無效的用戶端 ID

當您使用用戶端 ID 搭配產生的用戶端秘密時,通常會發生此錯誤。您必須建立未連接秘密的用戶端 ID。如需詳細資訊,請參閱應用程式用戶端的應用程式特定設定

相關資源

其他資訊

範例 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>" }