

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

# 定義驗證挑戰 Lambda 觸發程序
<a name="user-pool-lambda-define-auth-challenge"></a>

定義身分驗證挑戰觸發是 Lambda 函數，可在自訂身分驗證流程中維護挑戰序列。它宣告挑戰序列成功或失敗，並在序列尚未完成時設定下一個挑戰。

![\[挑戰 Lambda 觸發程序\]](http://docs.aws.amazon.com/zh_tw/cognito/latest/developerguide/images/lambda-challenges1.png)


**定義身分驗證挑戰**  
 Amazon Cognito 會叫用此觸發程序來啟動[自訂身分驗證流程](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html#amazon-cognito-user-pools-custom-authentication-flow)。

此 Lambda 觸發程序的請求包含 `session`。`session` 參數是一個陣列，其中包含目前身分驗證程序期間向使用者提出的所有挑戰。該要求也包含對應的結果。`session` 陣列依照時間順序存放挑戰詳細內容 (`ChallengeResult`)。挑戰 `session[0]` 代表使用者收到的第一個挑戰。

**Topics**
+ [定義驗證挑戰 Lambda 觸發程序參數](#cognito-user-pools-lambda-trigger-syntax-define-auth-challenge)
+ [定義驗證挑戰範例](#aws-lambda-triggers-define-auth-challenge-example)

## 定義驗證挑戰 Lambda 觸發程序參數
<a name="cognito-user-pools-lambda-trigger-syntax-define-auth-challenge"></a>

Amazon Cognito 傳遞至此 Lambda 函數的請求，是以下參數和 Amazon Cognito 新增至所有請求的[常用參數](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-working-with-lambda-triggers.html#cognito-user-pools-lambda-trigger-syntax-shared)之組合。

------
#### [ JSON ]

```
{
    "request": {
        "userAttributes": {
            "string": "string",
                . . .
        },
        "session": [
            ChallengeResult,
            . . .
        ],
        "clientMetadata": {
            "string": "string",
            . . .
        },
        "userNotFound": boolean
    },
    "response": {
        "challengeName": "string",
        "issueTokens": boolean,
        "failAuthentication": boolean
    }
}
```

------

### 定義驗證挑戰請求參數
<a name="cognito-user-pools-lambda-trigger-syntax-define-auth-challenge-request"></a>

 當 Amazon Cognito 叫用您的 Lambda 函數時，Amazon Cognito 會提供以下參數：

**userAttributes**  
代表使用者屬性的一或多組名稱/值。

**userNotFound**  
當您的使用者集區用戶端的 `PreventUserExistenceErrors` 設定為 `ENABLED` 時，Amazon Cognito 將會填入的布林值。值 `true` 表示使用者 ID (使用者名稱、電子郵件地址和其他詳細資訊) 與任何現有使用者不相符。當 `PreventUserExistenceErrors` 設定為 `ENABLED`，該服務不會通知應用程式有不存在的使用者。我們建議您的 Lambda 函數維持相同的使用者體驗並考慮延遲。如此一來，當使用者存在或不存在時，呼叫者無法偵測到不同的行為。

**工作階段**  
`ChallengeResult` 元素的陣列。每個都包含下列元素：    
**challengeName**  
下列挑戰類型之一：`CUSTOM_CHALLENGE`、`SRP_A`、`PASSWORD_VERIFIER`、`SMS_MFA`、`EMAIL_OTP``SOFTWARE_TOKEN_MFA`、`DEVICE_SRP_AUTH`、`DEVICE_PASSWORD_VERIFIER`、 或 `ADMIN_NO_SRP_AUTH`。  
當您定義驗證挑戰函式為已設定多重要素驗證的使用者發出`PASSWORD_VERIFIER`挑戰時，Amazon Cognito 會追蹤 `SMS_MFA`、 `EMAIL_OTP`或 `SOFTWARE_TOKEN_MFA`挑戰。這些是多重要素驗證碼的提示。在您的 函數中，包含處理來自 `SMS_MFA`、 `EMAIL_OTP`和 `SOFTWARE_TOKEN_MFA`挑戰的輸入事件。您不需要在定義驗證挑戰函數中叫用任何 MFA 挑戰。  
當您的函數正在確定使用者是否成功驗證，以及是否該發出權杖時，請務必檢查您定義驗證挑戰函數中的 `challengeName`，並且驗證是否與期望值相符。  
**challengeResult**  
如果使用者順利完成挑戰，則設定為 `true`，否則設定為 `false`。  
**challengeMetadata**  
您的自訂挑戰名稱。唯有在 `challengeName` 為 `CUSTOM_CHALLENGE` 時使用。

**clientMetadata**  
您可以做為 Lambda 函數的自訂輸入提供的一個或多個鍵值組，該函數是您用於定義驗證挑戰觸發程序所指定。若要將此資料傳遞至您的 Lambda 函數，您可以使用 [AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html) 和 [RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html) API 操作中的 `ClientMetadata` 參數。叫用定義驗證挑戰函數的請求不包含傳遞至 [AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html) 和 [InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) API 操作的 ClientMetadata 參數中的資料。

### 定義驗證挑戰回應參數
<a name="cognito-user-pools-lambda-trigger-syntax-define-auth-challenge-response"></a>

在回應中，您可以傳回身分驗證程序的下一個階段。

**challengeName**  
包含下一個挑戰名稱的字串。如果您想要向使用者提出新的挑戰，請在這裡指定挑戰名稱。

**issueTokens**  
如果您判斷使用者已完成身分驗證挑戰，請設定為 `true`。如果使用者未成功完成挑戰，請設定為 `false`。

**failAuthentication**  
如果您要結束目前的身分驗證程序，請設定為 `true`。若要繼續目前的身分驗證程序，請設定為 `false`。

## 定義驗證挑戰範例
<a name="aws-lambda-triggers-define-auth-challenge-example"></a>

此範例會定義一系列用來進行身分驗證的挑戰，且唯有在使用者完成所有挑戰時，才會發出權杖。當使用者使用 `SRP_A`和 `PASSWORD_VERIFIER`挑戰完成 SRP 身分驗證時，此函數`CUSTOM_CHALLENGE`會將叫用建立身分驗證挑戰觸發條件的 傳遞給他們。結合我們的[建立身分驗證挑戰範例](user-pool-lambda-create-auth-challenge.md#aws-lambda-triggers-create-auth-challenge-example)，此序列為挑戰 3 提供 CAPTCHA 挑戰，並為挑戰 4 提供安全問題。

使用者解決 CAPTCHA 並回答安全問題後，此函數會確認您的使用者集區可以發出權杖。不需要 SRP 身分驗證；您也可以將 CAPTCHA 和安全問題設定為挑戰一和挑戰二。如果您的定義身分驗證挑戰函數未宣告 SRP 挑戰，則使用者的成功完全取決於其對自訂提示的回應。

------
#### [ Node.js ]

```
const handler = async (event) => {
  if (
    event.request.session.length === 1 &&
    event.request.session[0].challengeName === "SRP_A"
  ) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = "PASSWORD_VERIFIER";
  } else if (
    event.request.session.length === 2 &&
    event.request.session[1].challengeName === "PASSWORD_VERIFIER" &&
    event.request.session[1].challengeResult === true
  ) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = "CUSTOM_CHALLENGE";
  } else if (
    event.request.session.length === 3 &&
    event.request.session[2].challengeName === "CUSTOM_CHALLENGE" &&
    event.request.session[2].challengeResult === true
  ) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = "CUSTOM_CHALLENGE";
  } else if (
    event.request.session.length === 4 &&
    event.request.session[3].challengeName === "CUSTOM_CHALLENGE" &&
    event.request.session[3].challengeResult === true
  ) {
    event.response.issueTokens = true;
    event.response.failAuthentication = false;
  } else {
    event.response.issueTokens = false;
    event.response.failAuthentication = true;
  }

  return event;
};

export { handler };
```

------