68
87

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【React】ユーザー認証をCognito + Amplifyで構築してみた ~ 構築準備編 ~

Last updated at Posted at 2020-11-25

はじめに

Reactで作成したWebアプリケーションのユーザー認証部分をCognito + Amplifyフレームワークで構築してみました。
本記事では、それぞれのサービスについて、Amplifyの設定方法についてまとめています。

完成画面

今回は、ユーザー名、パスワードとワンタイムパスワードの2段階認証を行います。そして、サインインをしたユーザーを識別し、トップページには「{ユーザー名}さんこんにちは!」という文字が出るようにします。

ezgif.com-gif-maker.gif

方法検討

要件

認証方法を考えるにあたり、条件は以下の通りです。

  • 静的コンテンツをS3に置いている
  • アプリケーション部分はLambdaで実装している
  • アプリケーション内でユーザーを管理しており、ユーザーに登録されている人だけ使えるようにしたい
  • 今後ユーザーのマイページも作りたいので、認証と合わせてユーザーを識別したい
  • パスワードはシステム管理者が管理しないようにするのがベター
  • ソーシャルアカウントは使わない
  • MFA(多要素認証)を使いたい

結論

この条件に沿って認証部分を考えた結果、Cognitoを利用することにしました。また、Cognitoと既存のWebアプリケーションを簡単に連携できるAWSのAmplifyフレームワークというものがあったので、こちらも使ってみることにしました。

使用するAWSサービスについて

Cognitoってなに?

公式サイトによると、次のように説明されています。

Amazon Cognito を使用すれば、ウェブアプリケーションおよびモバイルアプリに素早く簡単にユーザーのサインアップ/サインインおよびアクセスコントロールの機能を追加できます。Amazon Cognito は、数百万人のユーザーにスケールし、Facebook、Google、Amazon などのソーシャル ID プロバイダー、および SAML 2.0 によるエンタープライズ ID プロバイダーを使用したサインインをサポートします。

Cognitoでできること

今回のCognitoでやることは下記の通りです。

  • Webアプリケーションのユーザーの管理(パスワードなど含む)
  • ユーザーがサインインするときの認証

料金

料金は使った分だけです。最低料金もかかりません。
今回のように、ユーザープールの認証情報を使ってCognitoユーザープールに直接サインインする場合は50,000MAUの無料枠があります。50,000MAUを超えるアクティブユーザーがいる場合は、0.0055USD/MAUかかります。(人数幅によって多少減額あり。詳細はこちらをご覧ください。)
※1MAU=サインアップ、サインイン、トークンの更新またはパスワードの変更など、当該ユーザーに関わる ID 操作があったユーザー(アクティブユーザー)

参考:https://aws.amazon.com/jp/cognito/pricing/

Amplifyってなに?

公式サイトによると、次のように説明されています。

AWS Amplify は、モバイルとウェブのフロントエンドデベロッパーが、安全でスケーラブルなフルスタックアプリケーションを構築しデプロイできるようにする、AWS によるエンドツーエンドのソリューションです。Amplify を使用すれば、アプリケーションのバックエンドを数分で設定し、わずか数行のコードでそれをアプリケーションに接続できます。そして、3 ステップで静的なウェブアプリケーションをデプロイできます。

その中で、分析や認証などの機能を持つAWSリソースを構成するのに役立つ対話型のCLIを提供していたり、認証処理などの実装や画面の作成に使うライブラリ、UIコンポーネントを提供しているAmplifyフレームワークというものを使います。

Amplifyフレームワークでできること

今回Amplifyフレームワークでやることは下記の通りです。

  • Amplify CLIを使ってのCognitoユーザープールの構築
  • 既存のソースコードとCognitoの連携
  • サインイン画面作成
  • ユーザー情報の取得、サインアウト機能の実装

今回はフロントエンドフレームワークとしてReactを使いましたが、他にもReact Native、Angular、Vue、IonicやiOS/Android IDEでも使うことができます。

料金

Amplifyフレームワーク自体には料金はかかりません。

Amplify フレームワーク (ライブラリ、CLI、UIコンポーネント) を使用する場合は、基盤として使用する AWS のサービスに対してのみお支払いいただきます。Amplify フレームワークの使用には、追加料金は発生しません。

参考:https://aws.amazon.com/jp/amplify/pricing/?nc=sn&loc=3

手順

下記の流れで進めていきます。

本記事ではこちらの手順についてまとめています。

  1. Reactの開発環境の構築
  2. Amplifyの設定
  3. Amplify用のIAMユーザーの作成
  4. Amplifyの初期設定

下記の5番、6番については別記事 構築完成編 へ。
5. Cognitoユーザープールの作成
6. コード実装

やってみる

1. Reactの開発環境の構築

React環境を簡単に構築する環境構築ツールはcreate-react-app、パッケージマネージャーはyarnを使いました。

参考:新しい React アプリを作る

バージョン

  • node 14.15.0
  • yarn 1.22.10
  • create-react-app 4.0.0

2. Amplifyの設定

AmplifyをCLIで操作するために、Amplify CLIをインストールします。

$ yarn global add @aws-amplify/cli

そして、プロジェクトには、Amplifyのパッケージを追加します。

$ yarn add aws-amplify
$ yarn add aws-amplify-react
$ yarn add @aws-amplify/ui-react

3. Amplify用のIAMユーザーの作成

AWSでAmplifyが使うIAMユーザーの作成し、名前付きプロファイルにIAMユーザーを設定します。

$ amplify configure

上記のコマンドを実行すると、AWSのコンソールが自動で開くのでコンソールでIAMユーザーを作成します。その後、コマンドラインで対話形式で作成したIAMユーザーの認証情報をAWS CLIのcredentialsファイルに保存します。今回、プロファイル名はamplify-cognitoで保存しました。

詳しくは、こちらの記事のAWSアカウントの紐付けを参考にしました。
AWS Amplify CLIの使い方〜インストールから初期セットアップまで〜

ただ、Amplify用のIAMユーザーにAdministratorAccessのポリシーをアタッチするのは嫌だったので、こちらを参考に自分でポリシーを作成しました。不要そうなサービスへの権限を削除し、これでは権限が足りずエラーが出てしまったので、"cognito-idp:UntagResource"を追加しています。

※↓クリックするとIAMポリシーが見れます。

IAMポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "amplify:CreateApp",
                "amplify:CreateBackendEnvironment",
                "amplify:CreateBranch",
                "amplify:DeleteApp",
                "amplify:DeleteBackendEnvironment",
                "amplify:DeleteBranch",
                "amplify:GetApp",
                "amplify:GetBackendEnvironment",
                "amplify:ListApps",
                "amplify:ListBackendEnvironments",
                "amplify:ListBranches",
                "amplify:ListDomainAssociations",
                "amplify:UpdateApp",
                "cloudformation:CreateChangeSet",
                "cloudformation:CreateStack",
                "cloudformation:CreateStackSet",
                "cloudformation:DeleteStack",
                "cloudformation:DeleteStackSet",
                "cloudformation:DescribeChangeSet",
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStackResources",
                "cloudformation:DescribeStackSet",
                "cloudformation:DescribeStackSetOperation",
                "cloudformation:DescribeStacks",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:GetTemplate",
                "cloudformation:UpdateStack",
                "cloudformation:UpdateStackSet",
                "cognito-identity:CreateIdentityPool",
                "cognito-identity:DeleteIdentityPool",
                "cognito-identity:DescribeIdentity",
                "cognito-identity:DescribeIdentityPool",
                "cognito-identity:SetIdentityPoolRoles",
                "cognito-identity:GetIdentityPoolRoles",
                "cognito-identity:TagResource",
                "cognito-identity:UpdateIdentityPool",
                "cognito-idp:AdminAddUserToGroup",
                "cognito-idp:AdminCreateUser",
                "cognito-idp:CreateGroup",
                "cognito-idp:CreateUserPool",
                "cognito-idp:CreateUserPoolClient",
                "cognito-idp:DeleteGroup",
                "cognito-idp:DeleteUser",
                "cognito-idp:DeleteUserPool",
                "cognito-idp:DeleteUserPoolClient",
                "cognito-idp:DescribeUserPool",
                "cognito-idp:DescribeUserPoolClient",
                "cognito-idp:ListTagsForResource",
                "cognito-idp:ListUserPoolClients",
                "cognito-idp:UpdateUserPool",
                "cognito-idp:UpdateUserPoolClient",
                "cognito-idp:UntagResource",
                "iam:AttachRolePolicy",
                "iam:CreatePolicy",
                "iam:CreateRole",
                "iam:DeletePolicy",
                "iam:DeleteRole",
                "iam:DeleteRolePolicy",
                "iam:DetachRolePolicy",
                "iam:GetPolicy",
                "iam:GetRole",
                "iam:GetRolePolicy",
                "iam:GetUser",
                "iam:ListPolicyVersions",
                "iam:PassRole",
                "iam:PutRolePolicy",
                "iam:UpdateRole",
                "lambda:AddLayerVersionPermission",
                "lambda:AddPermission",
                "lambda:CreateEventSourceMapping",
                "lambda:CreateFunction",
                "lambda:DeleteEventSourceMapping",
                "lambda:DeleteFunction",
                "lambda:DeleteLayerVersion",
                "lambda:GetEventSourceMapping",
                "lambda:GetFunction",
                "lambda:GetFunctionConfiguration",
                "lambda:GetLayerVersion",
                "lambda:GetLayerVersionByArn",
                "lambda:InvokeAsync",
                "lambda:InvokeFunction",
                "lambda:ListEventSourceMappings",
                "lambda:ListLayerVersions",
                "lambda:PublishLayerVersion",
                "lambda:RemoveLayerVersionPermission",
                "lambda:RemovePermission",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "s3:CreateBucket",
                "s3:DeleteBucket",
                "s3:DeleteBucketPolicy",
                "s3:DeleteBucketWebsite",
                "s3:DeleteObject",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:HeadBucket",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:PutBucketAcl",
                "s3:PutBucketCORS",
                "s3:PutBucketNotification",
                "s3:PutBucketPolicy",
                "s3:PutBucketWebsite",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "*"
        }
    ]
}

これより少なくすることはできるかもしれないですが、この権限があれば今回のCognitoとAmplifyでユーザー認証を構築するのは問題なくできました!

4. Amplifyの初期設定

Amplifyの設定を行うために下記のコマンドを実行します。

$ amplify init

聞かれた通りにプロジェクト名や使っているエディターなどを入力、選択していきます。プロジェクト名や環境名は、AWS上に作成されるリソースの名前になります。

? Enter a name for the project qiitatest
? Enter a name for the environment dev
? Choose your default editor: IntelliJ IDEA
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: build
? Build Command:  yarn build
? Start Command: yarn start

そして、使うプロファイルについて聞かれるのでyと答え、先ほど3. Amplify用のIAMユーザーの作成で作成、保存したプロファイルamplify-cognitoを選択します。

? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use amplify-cognito

この設定が完了すると、プロジェクト内にamplifyフォルダsrc/aws-exports.jsが作成されます。

おわりに

Amplifyフレームワークの設定が完了しました!Amplify用のIAMユーザーの作成方法(ポリシーの内容は変わってきます)やAmplifyの初期設定についてはCognitoに限らず他のサービスでも共通です。
次の構築完成編では、Cognitoユーザープールの作成とソースコードも書いていきます!

68
87
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
68
87

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?