web-dev-qa-db-ja.com

パスワードなしのAWS Cognitoユーザープール

電話番号をアプリのユーザー名として使用し、ログインするたびに電話番号を確認するだけで簡単にサインアップできるようにしたい-面倒なパスワードを覚えているビジネスはありません。

AWS Cognitoユーザープールを使用して、各ユーザーのパスワードを強制的に設定するように要求するときにこれを行う方法。

各ユーザーにダミーのパスワードを使用し、必須のユーザー検証を構成することを考えました。ユーザーがサインアウトするたびに、次回ユーザーに電話番号の確認を自動的に求められるように、ユーザーを「確認解除」できます。また、ユーザーが確認された場合にのみ「ログイン」にアプリを接続します。

これが最良のアプローチかどうかを教えてください:(私はAWSを初めて使用し、このシナリオに関する投稿を見つけることができませんでした。

ありがとう!!

16
spar

AWS Cognitoは現在、パスワードなしの認証をサポートしていないため、外部に保存されたランダムパスワードを使用して回避策を実装する必要があります。認証フローは次のように実装できます。

  • ユーザーのサインアップ後(モバイル番号も要求し、必須にします)、 AWS KMS (セキュリティを強化するため)で暗号化されたDynamodbにもモバイル番号、ユーザー名、パスワードを保存します。
  • ユーザーが携帯電話番号を入力してログイン(フロントエンド)を押した後、バックエンドでユーザー名とパスワードの照合(パススルー)を自動的に実行し、MFAをトリガーしてユーザーの携帯電話のコードを送信できるように、認証チャレンジに携帯電話番号付きMFAを使用できますそして、AWS Cognito SDKを使用して(カスタムモバイルメッセージとチャレンジを実装せずに)検証します。
  • フローを手動で(MFAなしで)実装してSMS&検証)を送信する場合は、AWS SNSを目的に使用できます。

MFAの洞察を理解するには、次のコードサンプルを確認し、詳細については このリンク を参照してください。

    var userData = { 
        Username : 'username',
        Pool : userPool
    };

    cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);

    var authenticationData = {
        Username : 'username',
        Password : 'password',
    };

    var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);

    cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: function (result) {
            alert('authentication successful!')
        },

        onFailure: function(err) {
            alert(err);
        },

        mfaRequired: function(codeDeliveryDetails) {
            var verificationCode = Prompt('Please input verification code' ,'');
            cognitoUser.sendMFACode(verificationCode, this);
        }

    });

注:ここでは、モバイル番号付きMFAはMFAの目的ではなく、要件を満たすための回避策として使用されています。

15
Ashan

これは、OPが1つの秘密を使用しているため、OPが要求しているものとは少し異なりますが、この質問に答える他の人の助けになると思います。

Cognitoトリガーのカスタムラムダを作成することでこれを行うことができました:認証チャレンジの定義、認証チャレンジの作成、および認証チャレンジの検証。

私の要件は、バックエンドでsecretを使用して、Cognitoユーザーのアクセストークンと更新トークンを取得することでした。

Auth Challenge Lambdaを定義する

exports.handler = async event => {
  if (
    event.request.session &&
    event.request.session.length >= 3 &&
    event.request.session.slice(-1)[0].challengeResult === false
  ) {
    // The user provided a wrong answer 3 times; fail auth
    event.response.issueTokens = false;
    event.response.failAuthentication = true;
  } else if (
    event.request.session &&
    event.request.session.length &&
    event.request.session.slice(-1)[0].challengeResult === true
  ) {
    // The user provided the right answer; succeed auth
    event.response.issueTokens = true;
    event.response.failAuthentication = false;
  } else {
    // The user did not provide a correct answer yet; present challenge
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = 'CUSTOM_CHALLENGE';
  }
  return event;
};

Auth Challenge Lambdaの作成

exports.handler = async event => {
  if (event.request.challengeName == 'CUSTOM_CHALLENGE') {
    // The value set for publicChallengeParameters is arbitrary for our
    // purposes, but something must be set
    event.response.publicChallengeParameters = { foo: 'bar' };
  }
  return event;
};

認証チャレンジLambdaの検証

exports.handler = async event => {
  if (event.request.challengeName == 'CUSTOM_CHALLENGE') {
    // The value set for publicChallengeParameters is arbitrary for our
    // purposes, but something must be set
    event.response.publicChallengeParameters = { foo: 'bar' };
  }
  return event;
};

それから Amazon-cognito-identity-js を使用して、いくつかのJSを使用して秘密を提供し、トークンを取得することができました。

var authenticationData = {
  Username : 'username'
};
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
var poolData = {
  UserPoolId : '...', // Your user pool id here
  ClientId : '...' // Your client id here
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var userData = {
  Username : 'username',
  Pool : userPool
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);

cognitoUser.setAuthenticationFlowType('CUSTOM_AUTH');

cognitoUser.initiateAuth(authenticationDetails, {
  onSuccess: function(result) {
    // User authentication was successful
  },
  onFailure: function(err) {
    // User authentication was not successful
  },
  customChallenge: function(challengeParameters) {
    // User authentication depends on challenge response
    var challengeResponses = 'secret'
    cognitoUser.sendCustomChallengeAnswer(challengeResponses, this);
  }
});
3
redgeoff

これは機能する可能性がありますが、パスワードをdynamoDBに保存すると、セキュリティを考慮すると問題が発生する場合があります。代わりに、次のように試すことができます。

option#1:-ユーザーはユーザー名とパスワードでサインアップします。

  1. cognitoトリガーのセットアップ-ラムダ関数を使用できます。
  2. A.認証チャレンジの作成B.認証チャレンジの定義C.認証チャレンジ応答の検証
  3. クライアントアプリはCUSTOM_CHALLENGE認証フローを実装する必要があります。
  4. 登録済みの電話番号の入力をユーザーに依頼し、ユーザー名フィールドにこれを渡します。トリガーBはリクエストを理解し、フローをトリガーAに渡します。トリガーAはランダムコード5を生成します。AWSSNSサービスを使用して、SMSをユーザーの携帯電話番号に送信します
  5. トリガーCはOTPを検証し、ログインポイントが次を考慮することを許可します。電話番号をエイリアスとして設定します([確認済みの電話番号でサインインも許可する]を選択します)。電話番号フィールドを検証可能にする(これにより、ユーザーはOTPを受信できます)

option#1:-ユーザー名とパスワードなしでユーザーがサインアップします。Cognito setup

  1. 電話番号をエイリアスとして設定(確認済みの電話番号でサインインも許可するを選択)
  2. 電話番号フィールドを検証可能にする(これにより、ユーザーはOTPを受信できます)
  3. サインアップ中に、ユーザーにユーザー名とパスワードの入力を求めず、電話番号を尋ねるだけです
  4. ユーザー名とパスワードの両方が一意になるようにUUIDを生成し、これらを電話番号とともにcognitoに渡します
  5. Cognitoは、アカウント確認のためにOTPコードをユーザーに送信します。
  6. 上記のオプションで説明されているように、OTPログインセットアップトリガーのある電話番号の場合。

トリガーコードについては、 マルチサインインオプションのあるCognitoプールを参照 を参照してください

1
suryan