Authentication flow when MFA is required for a user in AWS Cognito

I am trying to add MFA for user authentication to an existing solution (built into Angular) for device management in AWS Cognito.

I am having trouble figuring out how to handle this particular answer correctly in terms of user experience. He actually feels overwhelmed, so I would be happy if someone else has pain points.

See Example Use 23. An example implementation, mine below:

authenticate(username: string, password: string): Observable<any> {

    // init cognitoUser here

    return new Observable((observer) => {
        cognitoUser.authenticateUser(authenticationDetails, {
            onSuccess: (result: any) => {},
            onFailure: (err: Error) => {},
            mfaRequired: (codeDeliveryDetails: any) => {

                // SMS has just been sent automatically 
                // and it needs to be confirmed within this scope

                // The example linked requests the code via 'confirm()'
                // which is awful UX...and since this is a service
                // probably non-compliant with best practice
                // However, without this 'confirm' at this point in                     
                // time, we have no confirmationCode below

                cognitoUser.sendMFACode(confirmationCode, {
                    onSuccess: (result) => {
                        observer.next(result);
                        observer.complete();
                    }, onFailure: (err: Error) => {
                        observer.error(err);
                        observer.complete();
                    }
                });
            }
        });
    });
}

Expected:

  • , MFA, sendMFACode (, - ?)

:

  • , MFA, ... 22?
  • "/" , sendMfaCode sendMfaCode sendMfaCode SMS.

- ?

+6
2

, API amazon-cognito-identity-js, . , . Amplify, .

Amplify .

import Amplify from 'aws-amplify'
import Auth from '@aws-amplify/auth'

let mfaRequired = false

Amplify.configure({
    Auth: {
        userPoolWebClientId: '',
        userPoolId: ''
    }
})

const logUserIn = (user) => {
  // Go forth and be happy
}

// Run me on your login form submit event
const login = async (username, password) => {
  const user = await Auth.signIn(username, password)

  if (user.challengeName === 'SMS_MFA') {
    // Change UI to show MFA Code input
    mfaRequired = true
    return
  }
  return logUserIn(user)
}

// Run me when the user submits theire MFA code
const senfMfaCode = async (mfaCode) => {
  const user = await Auth.confirmSignIn(mfaCode)
  return logUserIn(user)
}

, - amazon-cognito-identity-js, . .

cognitoUser . , , , , MFA, cognitoUser.sendMFACode() .

, this sendMFACode() ( ), authenticateUser() sendMFACode() ( , ).

import { CognitoUserPool, AuthenticationDetails, CognitoUser } from 'amazon-cognito-identity-js'

export let mfaRequired = false
export let cognitoUser = null

export const cognitoCallbacks = {
  mfaRequired () {
    // Implement you functionality to show UI for MFA form
    mfaRequired = true
  },
  onSuccess (response) {
    // Dance for joy the code gods be glorious.
  },
  onFailure () {
    // Cry.
  }
}

export const logUserIn = payload => {
  cognitoUser = new CognitoUser({
    Username: 'Matt Damon',
    Pool: new CognitoUserPool({
      UserPoolId: '',
      ClientId: ''
    })
  })
  return cognitoUser.authenticateUser(new AuthenticationDetails(payload), cognitoCallbacks)
}

export const sendMfaCode = MFACode => {
  cognitoUser.sendMFACode(MFACode, cognitoCallbacks)
}

, , , ,

  1. mfaRequired , , .
  2. / .

, !

+4

@stwiltz - JSFiddle? , , , - !!

0

Source: https://habr.com/ru/post/1693673/


All Articles