FlutterとAWSで始めるサービス開発 (3)AWS Cognito連携

#はじめに
AWSでモバイルアプリ開発といえば、Amplifyというのが今のAWSの押しであることは以前にも述べました。Amplifyを選択するとJavaScriptベースなのでReact Nativeを使ったモバイルアプリ開発に進むのが王道になります。
Flutterでモバイルアプリを作りたいという要求がベースにあって、そこからスタートしていない限りはなかなかこの組み合わせにたどり着くことはないのかなという気がします。また、AWSの公式にはDart版のAWS SDKがないので、その部分も敷居が高く、レアな組み合わせになってしまうのかなと思います。

公式ではなくても、https://pub.dev/packages?q=cognito で見たところ、いくつか十分実用的なAWS用パッケージが公開されており、それらパッケージを活用すればそこまで苦労せずにアプリケーションの構築は進められそうです。
以下、パッケージを探して気になったの2個のライブラリになります。
[Amazon Cognito Identity SDK for Dart](https://pub.dev/packages/amazon_cognito_identity_dart_2)
[flutterAmplify ](https://pub.dev/packages/flutter_aws_amplify_cognito)

前者はdartで実装されていてCognitoに特化したライブラリ、後者はFlutter版Amplifyを実現しようとしていて、iOS、Androidそれぞれのネイティブ実装で作りこんでいるライブラリです。シンプルにFlutterで色々なAWSサービスを使ってアプリケーションを開発していくなら前者のSDKはとても扱いやすそうです。さらには、AWSのsigv4実装も切り出されており、各種AWSサービスを使っていく上でも非常に便利に使えそうです。

前振りがながくなりましたが、Amazon Cognito Identity SDK for Dartを使ってCognito連携のアプリケーションを実装していこうと思います。

#ユーザー管理とCognito

単なるユーティリティ的なモバイルアプリケーションであれば必要ないと思いますが、永続的なデータを管理する場合や、ビジネス目的で開発するようなアプリケーションの場合、ユーザーにアカウントを作ってもらい、アカウントに関連付けてサーバー側で様々なデータ管理やサービスを行うのが理想的です。それを簡単に実現してくれるのがAmazon Cognitoです。Cognitoは大きくいくつかの機能に分かれますが、ユーザー管理を行いたい場合は、ユーザープールという機能を使います。ユーザープールは、[公式](https://aws.amazon.com/jp/cognito/?nc2=h_ql_prod_se_cog)から引用すると`Amazon Cognito ユーザープールは、何億人ものユーザーにスケールするセキュアなユーザーディレクトリを作成できます。フルマネージドサービスのユーザープールは、サーバーインフラストラクチャの立ち上げを気にすることなく、簡単にセットアップできます。`です。ユーザーIDの管理、認証等々の基本的な機能がすべて実装されており、月間5万アクティブユーザーまでは無料という至れり尽くせりなサービスです。

# アプリケーションの要件

アプリケーションの要件としては、以下を満たすようなものを作ってみたいと思います。

- 新規のID登録機能
    - メールアドレスを使った独自IDで登録
    - 別のSNSのID(Googleなど)を使ったIDで登録
- 登録したIDでのログイン機能
- 独自IDでパスワード忘れた場合のリセット機能

# Cognito ユーザープールの準備
まずは、AWSにアカウントを作りましょう。アカウントの作り方は[公式ページ](https://aws.amazon.com/jp/register-flow/)を参考に作成してください。今回の流れの中では無料枠に収まる範囲でしか使わないのでお金もかかりません。

## ユーザープール作成

[公式の手順](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/getting-started-with-cognito-user-pools.html)の[ステップ 1.ユーザープールを作成する](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)通りに作れば問題ありません。
ユーザープール作成画面に入り以下手順で進めました

1. ユーザープール名を自由に入力してください。アプリの利用者に目に入るわけではないので自分の管理したい名前で命名してかまいません。入力後、デフォルトを確認するを選択します<br>
![Cognito1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273926/d5a39a98-33b3-29a5-5030-d2f1beda2037.png)

1. 左側のナビゲーションメニューで__属性__ を選択し、__Eメールアドレスおよび電話番号__と__Eメールアドレスを許可__を選択します
![Cognito2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273926/326b281f-d685-3d90-a467-f56659f16834.png)

1. 左側のナビゲーションメニューで__確認__を選択し、__プールの作成__を押下します。
![Cognito3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273926/45630a2a-3952-7d16-207f-12b1eccd1e49.png)

1. ユーザープールの作成が完了したら、__プールID__を取得しましょう。後ほどモバイルアプリ側でIDを利用します。

![Cognito6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273926/7ff1c242-e2f2-233b-10d0-6cf391b4a1bc.png)


## アプリクライアントの作成

引き続きアプリケーションがCognitoユーザープールにアクセスするためアプリクライアントの作成を行います。
__全体設定__の__アプリクライアント__を選択します。
アプリクライアント名は自由につけてください。利用時に使うことはありません。今回は、__クライアントシークレットを作成__、__Lmabdaトリガのカスタム認証を有効にする__をOFFにし、その他はデフォルトで設定しています。

![Cognito4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273926/e9657052-efa7-f585-a953-29a8a8778c0b.png)

作成が完了したら、__アプリクライアントID__を取得しましょう。後ほどモバイルアプリ側でIDを利用します。


![Cognito5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273926/201ff5d8-6c81-e2db-98f1-b2fd1054169e.png)


# モバイルアプリの実装準備

まず、[Amazon Cognito Identity SDK for Dart](https://pub.dev/packages/amazon_cognito_identity_dart_2)をプロジェクトに組み込みます。__pubspec.yaml__ファイルの``dependencies``セクションに以下のようにパッケージを追記します。Visual Studio Codeのpliuginにて自動でパッケージの取得処理が実行されます。

``` yaml
dependencies:
  amazon_cognito_identity_dart_2: ^0.1.12+3
```

次に__lib/main.dart__に__amazon_cognito_identity_dart_2__パッケージをimportし、__CognitoUserPoolクラス__のインスタンスを作成します。__CognitoUserPoolクラス__のコンストラクタ第一引数は先ほど作成したプールの__プールID__、第二引数は先ほど作成したアプリクライアントの__アプリクライアントID__になります。

``` dart
import 'package:amazon_cognito_identity_dart_2/cognito.dart';

final userPool = new CognitoUserPool(
    '[プールID ex. ap-northeast-1_XXXXXXXX]', '[アプリクライアントID]');
```

# まとめ

ここまでの準備で、Cognito連携をしたモバイルアプリ開発の準備ができました。次回「[(4)AWS Cognitoへの新規アカウント登録](https://qiita.com/makotomi/items/d2e399d16c0931ad3228)」では、実際にモバイルアプリにユーザー登録機能を実装していきたいと思います。