编程语言
首页 > 编程语言> > javascript – AWS Cognito中用户需要MFA时的身份验证流程

javascript – AWS Cognito中用户需要MFA时的身份验证流程

作者:互联网

我正在尝试将用于用户身份验证的MFA添加到AWS Cognito中用于设备管理的现有解决方案(内置于Angular中).

从用户体验的角度来看,我无法弄清楚如何很好地处理这个特定的响应.它实际上感觉很破碎,如果有其他人在这里经历过痛点,那就太爱了.

有关示例实现,请参见Use Case 23.,以下是:

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();
                    }
                });
            }
        });
    });
}

预期:

>如果用户成功验证但尚未通过MFA添加此设备,我们可以管理重定向到相应的确认代码表单页面并手动触发sendMFACode函数(可能通过某种有限的会话?)

发行/ S:

>我们没有会话,所以我们无法向用户询问在此登录屏幕之外自动发送的MFA代码… catch 22?
>在登录表单中添加另一个显示/隐藏字段不起作用,因为它会多次点击sendMfaCode函数,导致发送多个SMS代码.

有没有人有任何运气退出这一流程?

解决方法:

虽然我确信非常有才华的人在亚马逊 – cognito-identity-js API上工作,但它的设计却很糟糕.这就是为什么它被贬低了.我的个人建议是迁移到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's 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时无法通知您的UI,然后再调用cognitoUser.sendMFACode().

请记住,文档显示将此传递给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)
}

这是一个超级基本的实现,除此之外,你可以,

>只需覆盖外部模块中的mfaRequired函数即可执行任何操作.
>将整个事物包装在pub / sub插件中并订阅事件.

希望有所帮助!

标签:javascript,sdk,amazon-web-services,aws-cognito,multi-factor
来源: https://codeday.me/bug/20190522/1153188.html