AWS Amplify + Cognito + Next.jsで認証付きページ(ログインが必要なページ)を作る方法です。
やりたいこと
上記のような要件を満たしたいたいため、 画面側をAmplify(frontent) + Next.jsで作成し、認証機能をAmplifyのAuthenticationを使い、認証ユーザ(管理ユーザ)のデータをCoginitoで管理するようにしました。
AWS Amplifyとはなにかと一言で説明するのは難しいのですが、自分が思うのはAmplifyはインターフェイスみたいなもので、裏側ではAWSの各種サービスを組み合わせ、オーケストレーションしているサービスみたいなものかなと思います。 Amplifyから利用されるサービスはIAM、Lambda、CloudFormation、Cognito、AppSyncなどがあります。できることは結構多いです(そして覚えることも)。
主な Frameworkには例として、以下のものがあります
ローカル環境に、npmを利用して、Amplify CLIをインストールします。
npm install -g @aws-amplify/cli
Amplify CLIの初期設定として、デプロイを行うユーザ(IAM)を作成し、アクセスキーを登録します。 ※ 詳細はこちらのビデオを参照、https://youtu.be/fWbM5DLh25U
amplify configure
ひとまず、ローカルで動作するNext.jsの環境を作ります。
こちらの記事のような、プレーンなNext.jsでもよいですし、create-next-appでもいいです。
Amplifyのbackend機能は、notifications, analytics, apiなど多数の機能を選択して利用することができます。今回はAuthenticationだけ利用したいのでそれを追加します。
プロジェクトのAmplifyを定義するため、ルートディレクトリで以下を実行します。
amplify init
基本的にはデフォルトで良いですが、以下の点を変えます。
.next
としますNote: It is recommended to run this command from the root of your app directory
? Enter a name for the project nextamplified
The following configuration will be applied:
Project information
| Name: nextamplified
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: .next
| Build Command: npm run-script build
| Start Command: npm run-script start
initが行われるとローカルの環境に、
amplify
というディレクトリが作成され、そこにバックエンドをのスタックを定義するためのコードが追加されていく。src
ディレクトリに aws-exports.js
というファイルが作成され、amplifyで作成したサービスの設定を保持する。これによりamplifyクライアントがバックエンドサービスの情報を取得することができる。Amplify CLIを使ってカテゴリーを追加・削除したり、バックエンドの設定を更新すると、aws-exports.jsの設定が自動的に更新されます。.gitignore
にamplifyで追加されたファイルの中でコミットが不要なものが追加されるまた、AWS Amplifyにプロジェクトが作成され、そのbackendに dev
という環境が作成されます。
その際、自動で作成されるAWS側のサービスとして
CloudFormationのログをみると以下のようになっているので、おそらくAmplifyがcloudformationをキックして各種サービス生成するという流れなのかなと思います。
Amplify環境ができたので次に認証機能を追加します。
amplify add auth
Cognitoの設定を聞かれるので、回答していきます。 今回はEmailでのログインを行いたいのでそのように設定します。
Using service: Cognito, provided by: awscloudformation
The current configured provider is Amazon Cognito.
Do you want to use the default authentication and security configuration? Default configuration
Warning: you will not be able to edit these selections.
How do you want users to be able to sign in? Email
Do you want to configure advanced settings? No, I am done.
Successfully added auth resource xyzaadminb16d7f70 locally
設定ができたら、pushコマンドでデプロイを行います。
amplify push
Authの設定がAmplify上に追加されます
✔ Successfully pulled backend environment dev from the cloud.
Current Environment: dev
| Category | Resource name | Operation | Provider plugin |
| -------- | --------------------- | --------- | ----------------- |
| Auth | nextamplifiedcxxxxxxx | Create | awscloudformation |
実行すると以下のサービスにamplify用の設定が追加されます
backendがデプロイされたので、今度はフロント側に認証機能を呼び出す処理を追加します。
Amplify用のjsライブラリをインストールします。今回は以下の2つを利用します。
npm install aws-amplify @aws-amplify/ui-react
aws-amplify
... 作成されたアプリケーションでAmplifyを動かすためのメインライブラリ@aws-amplify/ui-react
... Reactで構成されたアプリケーションを構築するためのUIコンポーネントindex.tsxを以下のようにします
import { Amplify } from 'aws-amplify';
import { NextPage } from 'next';
import React from 'react';
import { AmplifyAuthenticator } from '@aws-amplify/ui-react';
import awsExports from '../aws-exports';
Amplify.configure({ ...awsExports });
const Index: NextPage<{}> = () => {
return (
<AmplifyAuthenticator>
<div>ようこそ</div>
</AmplifyAuthenticator>
)
};
export default Index;
保存し、localhost:3000にアクセスすると、初回はログインしていないので、ログイン画面が表示されます。
今回はサインアップを行わないので、<AmplifyAuthenticator>
内のslot AmplifySignIn
にhideSignUpを追加します。
<AmplifyAuthenticator>
<AmplifySignIn slot="sign-in" hideSignUp />
</AmplifyAuthenticator>
AWSのコンソールからCognito画面を呼び出し、その中でユーザを登録します。 ユーザ名がemailとなるよう設定したので、usernameはメールアドレスで指定します。
ログインが行われ認証されたユーザのみUIが表示されるようになりました。
ローカルで認証機能の確認できたので、Amplifyにdeployをします。プロジェクトのgitを作成し、github等のリモートホストにpushします。
Next.jsのSSRを利用するため、hostingを追加します。
amplify add hosting
? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type Continuous deployment (Git-based deployments)
? Continuous deployment is configured in the Amplify Console. Please hit enter once you connect your repository
コンソールが開くのでfrontendタブから該当するgitのリモート先を選択し、設定します。 設定が完了するとビルドが実行されるので完了するのを待ちます。
このときにデプロイ先のCloudFront、S3が作られます。
デプロイ完了後、作成されたURL https://main.xx.amplifyapp.comにアクセスすると画面が表示されます。
以上まずログインができるところまでを書きました。実際にcognitoのユーザが正しいかなどは後で書きます。
上に書いたとおり、2021/06/14現在最新のNext.jsのバージョンはv10.2.3、現状Amplifyがサポートしているのがv9であり10.2.0より上のバージョンだとLambda Edgeがエラーになるようで、Cloudfrontのエラーがでて動かないです。 https://github.com/aws-amplify/amplify-console/issues/1915 オフィシャルのドキュメントでは以下のように書かれています。
https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/server-side-rendering-amplify.html
Your Next.js app uses unsupported features You can deploy an app created with Next.js version 10. However, Amplify doesn't currently support the full feature set. Amplify supports all features of Next.js versions 9.x.x, except for Incremental Static Regeneration (ISR).
コンソールから削除を選択した場合ローカル環境のamplifyディレクトリが残ってしまうので、以下のコマンドで削除するほうがよいです。
amplify delete