Amazon Cognito User Pools supports customizing the authentication flow to enable custom challenge types. These challenge types may include CAPTCHAs or dynamic challenge questions. To define your challenges you need to implement three Lambda triggers.

> For more information about working with Lambda Triggers for custom authentication challenges visit [Amazon Cognito Developer Documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html).

## Custom Authentication in Amplify

To enable a custom authentication flow update your `awsconfiguration.json` file and set `authenticationFlowType` to `CUSTOM_AUTH`. 

```json
{
  "CognitoUserPool": {
    "Default": {
      "PoolId": "XX-XXXX-X_abcd1234",
      "AppClientId": "XXXXXXXX",
      "Region": "XX-XXXX-X"
    }
  },
  "Auth": {
    "Default": {
      "authenticationFlowType": "CUSTOM_AUTH"
    }
  }
}
```

In your app code call `signIn` with a dummy password. Custom challenges need to be answered using the `confirmSignIn` method:

```swift
AWSMobileClient.default().signIn(username: username, password: "dummyPassword") { (signInResult, error) in
            
    if let signInResult = signInResult {
        if (signInResult.signInState == .customChallenge) {
            // Retrieve challenge details
        }
    }
            
}

```

Get the challenge details from the user and then call `confirmSignIn`

```swift
AWSMobileClient.default().confirmSignIn(challengeResponse: "<Challenge Response>",
                                                completionHandler: { (signInResult, error) in
    if let error = error  {
        print("\(error.localizedDescription)")
    } else if let signInResult = signInResult {
        switch (signInResult.signInState) {
        case .signedIn:
            print("User is signed in.")
        default:
            print("\(signInResult.signInState.rawValue)")
        }
    }
                                                    
})
```

### Lambda Trigger Setup

The Amplify CLI can be used to generate triggers required by a custom authentication flow. See the [CLI Documentation](/cli/usage/lambda-triggers) for details. The CLI will create a custom auth flow skeleton that you can manually edit. 

> More information on available triggers can be found in the [Cognito documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html).

`AWSMobileClient` assumes the custom auth flow starts with username and password. If you want a passwordless authentication flow, modify your **Define Auth Challenge** Lambda trigger to bypass the initial username/password verification and proceed to the custom challenge:

```javascript
exports.handler = (event, context) => {
  if (event.request.session.length === 1 && 
    event.request.session[0].challengeName === 'SRP_A') {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = 'CUSTOM_CHALLENGE';
  } else if (
    event.request.session.length === 2 &&
    event.request.session[1].challengeName === 'CUSTOM_CHALLENGE' &&
    event.request.session[1].challengeResult === true
  ) {
    event.response.issueTokens = true;
    event.response.failAuthentication = false;
  } else {
    event.response.issueTokens = false;
    event.response.failAuthentication = true;
  }
  context.done(null, event);
};
```
