「amplify init」を使わず必要最低限構成でCognitoを用いたAmplifyを使ってみる

本投稿は TECOTEC Advent Calendar 2021 の13日目の記事です。

こんにちは、証券フロンティア事業部の西永です。
今回も趣味の中で見つけた、AWS amplify(以下 amplify)のライブラリを使うのにamplifyを使わない構成を紹介します。

そもそもamplifyとは

AWS Amplify は、それぞれを連携させたり個別で使用したりできる、ツールとサービスのセットです。これらの機能により、フロントエンドウェブおよびモバイルのデベロッパーが、AWS によるスケーラブルなフルスタックアプリケーションをビルドできるようにします。Amplify を使用するお客様は、数分の内にバックエンドを構成しアプリケーションと接続でき、また、静的なウェブアプリケーションのデプロイは数クリックだけで実行できます。さらに、AWS コンソールの外部でも、簡単にアプリケーションコンテンツの管理が行えます。 aws.amazon.com

色々書いてありますが、これを使うことでフロントエンジニアの知識だけでも良い感じにバックエンドの方まで構築できるといった代物です。
なのですが……これには一つ重大な懸念点があります。

それは構築するにあたり初期設定で「amplify init」を実行した際、「AWS管理者権限のアクセスキーとシークレットキーを要求される点」です。

一人で組む場合や新規プロジェクトだとAWS管理者権限を要求されてもどうとでもなると思いますが、既存プロジェクトやセキュリティを気にする場合だとおいそれとAWS管理者権限のキーを渡す訳にはいきません。

そこで紹介するのが今回の方法です。
※Amplifyでは本来設定をAWS上に保管できる機能がありますが、そちらは今回使いません

やり方

サーバー側の設定

1. AWSにログインし、「Cognito」>「ユーザープール」に移動して「ユーザープールを作成する」 f:id:teco_nishinaga:20210818141944p:plain

2. 用途に合わせてユーザープールを作成(今回はデフォルトで作成) f:id:teco_nishinaga:20210818142139p:plain f:id:teco_nishinaga:20210818142859p:plain

ここにある「プール ID」(ユーザープールID)は後で使うので覚えておくこと。

3. 左タブにある「アプリクライアント」>「アプリクライアントの追加」を選択し、アプリクライアントを作成
※作成する際、「クライアントシークレットの作成」のチェックは外しておくこと
※今回は簡略化のため、デフォルトの状態から上記の設定と「ユーザー名パスワードベースの認証を有効にする (ALLOW_USER_PASSWORD_AUTH)」にチェックを入れる f:id:teco_nishinaga:20210818143319p:plain

f:id:teco_nishinaga:20210818145020p:plain
作成するとアプリクライアント IDができる

ここにある「アプリクライアントID」も後で使うので覚えておくこと。

4. 「Cognito」>「IDプールの管理」から新規でIDプールの作成を行う
余談:Cognitoの機能だけ使う場合だとIDプールは必要ないが、Amplifyのライブラリを使う場合は設定が必須なので作成が必要

作成時、認証プロパイダーを開き、先程覚えた「プール ID」と「アプリクライアントID」を「ユーザープールID」と「アプリクライアントID」に入力してプールを作成する。 f:id:teco_nishinaga:20210818150718p:plain

f:id:teco_nishinaga:20210818151116p:plain
ロールは適宜作成(今回はデフォルト)
f:id:teco_nishinaga:20210818151347p:plain
出来たらこの画面に飛ぶ

ここにある「ID プールの ID」は後で使うので覚えておくこと。

クライアント側の設定

今回は手軽に作れるNode.jsで作成します。
(他OSでもサーバー側の手順は同様です)

1. プログラムを書く
今回は例として、サインアップ→認証→ログインまでの一連の流れをコンソール上で完結できるよう書いてみました。

import Amplify, { Auth } from "aws-amplify";
import readline from "readline";

Auth.default.configure({
    Auth: {
        // ID プールのID
        identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab',
        // Cognitoのリージョン(ユーザープールIDの「_」で区切った左側 例: ap-northeast-1)
        region: 'XX-XXXX-X',
        // IDプールのリージョン(ID プールのIDの「:」で区切った左側 例: ap-northeast-1)
        identityPoolRegion: 'XX-XXXX-X',
        // ユーザープールID
        userPoolId: 'XX-XXXX-X_abcd1234',
        // アプリクライアントID
        userPoolWebClientId: 'a1b2c3d4e5f6g7h8i9j0k1l2m3',
    }
});

const username = await readInput("ユーザーネームを入力してください:");
const password = await readInput("パスワードを入力してください:");
const email = await readInput("Eメールアドレスを入力してください:");

await Auth.signUp(username, password, email);

console.log("ユーザーを作成しました!");

await Auth.confirmSignUp(
  username,
  await readInput("認証番号を入力してください:")
);

console.log("ユーザーの認証に成功しました!");

const user = await Auth.currentAuthenticatedUser();

console.log(user);

// コンソールから入力を受け付ける
function readInput(question) {
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  return new Promise((resolve) => {
    rl.question(question, (answer) => {
      rl.close();
      resolve(answer);
    });
  });
}

クライアント側の設定はこれだけです。
次は実際に実行してみます。

実行編

f:id:teco_nishinaga:20210818175855p:plain
ユーザーネーム、パスワード、Eメールアドレスを入力してEnter
f:id:teco_nishinaga:20210818190125p:plain
認証番号がEメールに届くので……
f:id:teco_nishinaga:20210818190434p:plain
その認証番号を入力してEnter

Cognitoのユーザー情報がずらっと出てきたら完了です。
(エラーが発生した場合は既に同ユーザー名で作成済み、入力した情報 or AWSの設定が間違っている等色々ありますので、エラーメッセージをよく確認してみてください)

ここから、IDプールの設定時に「ロールは適宜作成(今回はデフォルト)」で適当に流したロール設定を用途に合わせて設定していくことにより、認証したユーザーだけAWSの機能が使えるよう機能を拡張していくことができます。
お疲れさまでした。

補足

認証に成功すると、CognitoのユーザープールとIDプールのページにそれぞれ情報が追加されます。

f:id:teco_nishinaga:20210818190834p:plain
ユーザープールにはユーザが追加されている
f:id:teco_nishinaga:20210818191035p:plain
IDプールはカウンタが増えている

Amazon Web Servicesおよびかかる資料で使用されるその他の AWS 商標 は、米国および/またはその他の諸国における、Amazon.com, Inc. またはその関連会社の商標です。

tecotec.co.jp