Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cognito paswordless auth via link

I'm trying to implement auth via link without password. E.g. user enter his email -> cognito send an email with link that user can click and login. It

It is supported by cognito via custom challenge. E.g. https://aws-amplify.github.io/amplify-js/media/authentication_guide#using-a-custom-challenge

I have created DefineAuthChallenge, CreateAuthChallenge, VerifyAuthChallenge lambda function that associated with my cognito pool. CreateAuthChallenge generate code that is send to user email with link to site.

Next i was planning to grab that code from url on site and login user via it like its in docs

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

But here is the problem. Auth.sendCustomChallengeAnswer require user object that is passed from Auth.signIn. But if user just click link from email there wont be any user object at all. And amplify lib dont save that middle session user object, so on page reload its lost. It is saving only if auth completed to its storage https://github.com/aws-amplify/amplify-js/blob/master/packages/amazon-cognito-identity-js/src/CognitoUser.js#L175

So the question is how can i save & reconstruct user object from Auth.signIn function on page reload. Or if there a better approach to sign in via link without password?

like image 756
Aldarund Avatar asked Oct 12 '18 22:10

Aldarund


1 Answers

To solve this first you need to save username and session into localstorage or cookies. Then when user go through link this code can be used:

 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)
like image 81
Aldarund Avatar answered Nov 15 '22 09:11

Aldarund