通过链接进行 Cognito 无密码身份验证

Ald*_*und 5 authentication amazon-web-services amplifyjs amazon-cognito aws-amplify

我正在尝试通过没有密码的链接实现身份验证。例如,用户输入他的电子邮件 -> cognito 发送一封带有用户可以单击并登录的链接的电子邮件。它

Cognito 通过自定义挑战支持它。例如https://aws-amplify.github.io/amplify-js/media/authentication_guide#using-a-custom-challenge

我已经创建了与我的认知池相关联的DefineAuthChallenge, CreateAuthChallenge, VerifyAuthChallengelambda 函数。CreateAuthChallenge生成发送到用户电子邮件和站点链接的代码。

接下来我计划从网站上的 url 中获取该代码并通过它像在文档中一样登录用户

Auth.signIn(username)
    .then(user => {
        if (user.challengeName === 'CUSTOM_CHALLENGE') {
            Auth.sendCustomChallengeAnswer(user, challengeResponse)
                .then(user => console.log(user))
                .catch(err => console.log(err));
        } else {
            console.log(user);
        }
    })
    .catch(err => console.log(err));
Run Code Online (Sandbox Code Playgroud)

但问题就在这里。 Auth.sendCustomChallengeAnswer需要从Auth.signIn. 但是,如果用户只是单击电子邮件中的链接,则根本不会有任何用户对象。并且放大 lib 不保存该中间会话用户对象,因此在页面重新加载时丢失了。它仅在身份验证完成后保存到其存储https://github.com/aws-amplify/amplify-js/blob/master/packages/amazon-cognito-identity-js/src/CognitoUser.js#L175

所以问题是如何Auth.signIn在页面重新加载时从函数中保存和重建用户对象。或者是否有更好的方法通过链接登录而无需密码?

Ald*_*und 4

要解决这个问题,您首先需要将用户名和会话保存到本地存储或 cookie 中。然后当用户通过链接时可以使用此代码:

 const userPoolData = {
    UserPoolId: process.env.COGNITO_POOL_ID,
    ClientId: process.env.COGNITO_POOL_WEB_CLIENT_ID,
    Storage: customStorageClass // default is localstorage
  }

  const userPool = new CognitoUserPool(userPoolData)

  const userData = {
    Username: getUsernameFromCookiesOrLocalstorage,
    Pool: userPool,
    Storage: customStorageClass // default is localstorage
  }
  const user = new CognitoUser(userData)
  user.Session = getSessionFromCookiesOrLocalstorage
  Auth.sendCustomChallengeAnswer(user, code)
Run Code Online (Sandbox Code Playgroud)