AWS Amplifyで、既存のAmazon Cognitoを使う方法を探してみた

AWS Amplifyでは、Authentication moduleを使うことで、簡単にAmazon Cognitoの新しい環境が作れます。
Authentication

 
ただ、Amplify CLIを使って既存のAmazon Cognito環境を利用する方法が見当たらなかったので、調べた時のメモを残します。

 
目次

 

環境

 

結論

これらのissueがあるように、現時点のAmplify CLIでは既存のCognitoを指定できないようです。

 
そのため、既存のCognitoを使いたい場合は、 $ amplify auth add で作るのではなく、Amplify.configure() の引数に対象のCognito情報を入れる必要があります。

また、$ amplify auth add が必要なAWS Amplify Storage moduleについても、 $ amplify storage add で環境を作るのではなく、 Amplify.configure() の引数に指定する形となります。

 
つまり、現時点で既存のCognitoを使いたい場合は

  • $ amplify auth add
  • $ amplify storage add

ができないようです。

 
以降、$ amplify auth add で既存のCognitoを使えないかを試してみた時のログです。

 

試してみた

実行前の既存のユーザープールは以下です。これを使いたいとします。

$ aws cognito-idp list-user-pools --max-results 20
{
    "UserPools": [
        {
            "Id": "us-east-1_ZTS1WF17W",
            "Name": "directiveauthuserpool-dev",
            "LambdaConfig": {},
            "LastModifiedDate": 1562661761.134,
            "CreationDate": 1562661761.134
        }
    ]
}

 
amplify initします。特別なことはしていません。

$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project existingawsresources
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using none
? Source Directory Path:  src
? Distribution Directory Path: dist
? Build Command:  npm run-script build
? Start Command: npm run-script start
Using default provider  awscloudformation

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html

? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default

 
続いて AmplifyのAuthenticationモジュールを追加します。既存のものが使えるかなと思い名前を合わせてみました。

$ amplify auth add
Using service: Cognito, provided by: awscloudformation
 
 The current configured provider is Amazon Cognito. 
 
 Do you want to use the default authentication and security configuration? Manual configuration
 Select the authentication/authorization services that you want to use: User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage features for images or oth
er content, Analytics, and more)
 Please provide a friendly name for your resource that will be used to label this category in the project: existingawsresourcesb5bd8fa8b5bd8fa8

# 名前が既存と同じになるよう指定する
 Please enter a name for your identity pool. directiveauthidpool
 Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) No
 Do you want to enable 3rd party authentication providers in your identity pool? No

# こちらも同様
 Please provide a name for your user pool: directiveauthuserpool
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Username
 Multifactor authentication (MFA) user login options: OFF
 Email based user registration/forgot password: Enabled (Requires per-user email entry at registration)
 Please specify an email verification subject: Your verification code
 Please specify an email verification message: Your verification code is {####}
 Do you want to override the default password policy for this User Pool? No
 Warning: you will not be able to edit these selections. 
 What attributes are required for signing up? (Press <space> to select, <a> to toggle all, <i> to invert selection)Email
 Specify the app's refresh token expiration period (in days): 30
 Do you want to specify the user attributes this app can read and write? No
 Do you want to enable any of the following capabilities? (Press <space> to select, <a> to toggle all, <i> to invert selection)
 Do you want to use an OAuth flow? No
? Do you want to configure Lambda Triggers for Cognito? No

 
この時にできあがったファイルはこちら

 
続いて、既存のものに合わせるべく、不要なところを修正・削除します。

その後、 amplify auth update

$ amplify auth update
Please note that certain attributes may not be overwritten if you choose to use defaults settings.
Using service: Cognito, provided by: awscloudformation
 What do you want to do? Apply default configuration without Social Provider (Federation)
Successfully updated resource existingawsresourcesb5bd8fa8b5bd8fa8 locally

 
update後の変更点はこちら。

 
amplify push すると成功。

$ amplify push

Current Environment: dev

| Category | Resource name                        | Operation | Provider plugin   |
| -------- | ------------------------------------ | --------- | ----------------- |
| Auth     | existingawsresourcesb5bd8fa8b5bd8fa8 | Create    | awscloudformation |
? Are you sure you want to continue? Yes
...
✔ All resources are updated in the cloud

 
しかし、AWS CLIで見ると、同じ名前で別のユーザープールができあがっていました。残念。
list-user-pools — AWS CLI 1.16.197 Command Reference

$ aws cognito-idp list-user-pools --max-results 20
{
    "UserPools": [
        {
            "Id": "us-east-1_MoYYcoq4F",
            "Name": "directiveauthuserpool-dev",
            "LambdaConfig": {},
            "LastModifiedDate": 1563375883.473,
            "CreationDate": 1563375883.473
        },
        {
            "Id": "us-east-1_ZTS1WF17W",
            "Name": "directiveauthuserpool-dev",
            "LambdaConfig": {},
            "LastModifiedDate": 1562661761.134,
            "CreationDate": 1562661761.134
        }
    ]
}

 

対応

こんな感じのJavaScriptを書いてみました。

use_aws_exportsがtrueの時は aws-exports.js を使い、falseの時は、既存のCognito情報を使っています。

const signInUsingCognito = async (use_aws_exports) => {
  if (use_aws_exports) {
    Amplify.configure(awsconfig);
  }
  else {
    Amplify.configure({
      Auth: {
        // TODO replace for your environment
        identityPoolId: 'xxx',
        region: 'us-east-1',
        userPoolId: 'us-east-1_ZTS1WF17W',
        userPoolWebClientId: 'xxx',
      }
    });
  }

  const username = document.getElementById('user').value;

  await Auth.signIn(username, '11111111')
    .then( user => {
      showUsername(user);
      document.getElementById('message').innerText = ''
    })
    .catch(e => {
      console.log(Object.keys(e));
      console.log(e['message']);
      document.getElementById('message').innerText = e['message'];
    })
};

 
結果です。

aws-exports.jsを使った場合は、Amplify Authenticationモジュールで新規作成したため、ユーザープールにユーザーが存在していないことから、エラーとなりました。

(3) ["code", "name", "message"]0: "code"1: "name"2: "message"length: 3__proto__: Array(0)
app.js:59 User does not exist.

 
一方、既存のCognitoにはユーザーがいるため、サインインができました。

foo
CognitoUser {username: "foo", pool: CognitoUserPool, Session: null, client: Client, signInUserSession: CognitoUserSession, …}

 
今回はCognitoだけでしたが、もし他のリソースを指定したい場合は、AmplifyのGetting Started の下部にある Configuration Parameters for existing AWS resources に記載があります。
Getting Started - Amplify JavaScript

 

ソースコード

GitHubに上げました。 existing_aws_resources ディレクトリ以下が今回のファイルです。
https://github.com/thinkAmi-sandbox/AWS_AppSync_Amplify-sample