とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど
各種SNSのフォローもよろしくお願いいたします。

Amplifyを使ってWebアプリを作ろう(認証機能編)

こんにちは。 アドベントカレンダー19日目です。 今年はフロントエンドまわりであれこれ開発することが多かったので、振り返りを兼ねてこれからフロントエンド開発を始める方向けに入門編としてお送りしています。 最終日の25日には何かアプリケーションができていることが目標です。

↓最初から読み始めたい方はこちらか↓

devops-blog.virtualtech.jp

おさらい

今回のはなし

前回の第18回でAmplifyを使って開発を進めるための準備が整いました。これから必要なバックエンド環境を追加しながらサービスやプロダクトの開発を進めていきます。今回は、Cognitoを使った認証機能を追加してみましょう。

準備

Amplifyで認証機能を追加するためには次のコマンドを実行します。

amplify add auth

コマンドを実行した際に幾つかの質問に答える必要があります。回答例として参考にしてください。

Do you want to use the default authentication and security configuration? (Use arrow keys)
❯ Default configuration 
  Default configuration with Social Provider (Federation) 
  Manual configuration 
  I want to learn more. 

「デフォルトの認証およびセキュリティ構成を使用しますか?」というふうに聞かれていますので、今回はデフォルト設定のまま進みます。

How do you want users to be able to sign in? (Use arrow keys)
❯ Username 
  Email 
  Phone Number 
  Email or Phone Number 
  I want to learn more.

ユーザーがサインインする際に使用する情報について聞かれていますので、デフォルトで選択されているUsernameのまま進みます。

Do you want to configure advanced settings? (Use arrow keys)
❯ No, I am done. 
  Yes, I want to make some additional changes. 

詳細な設定をするかどうか聞かれていますが今回は特に何もしないため、No, I am done.が選択された状態で進みます。

少し待つとコマンドの実行が終了しますが、この時点ではまだAWS上にリソースが作成されていません。 次に現在の状態を確認してみましょう。

amplify status
    Current Environment: dev
    
┌──────────┬─────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name       │ Operation │ Provider plugin   │
├──────────┼─────────────────────┼───────────┼───────────────────┤
│ Auth     │ xxxxxxxxxxxxxxxxxxx │ Create    │ awscloudformation │
└──────────┴─────────────────────┴───────────┴───────────────────┘

上のような情報が表示されます。これは、新しく認証機能を追加しようとしている状態です。 この状態で次のコマンドを実行してみましょう。

amplify push
? Are you sure you want to continue? (Y/n)

のように聞かれますが、エンターを押してそのまま進みます。

Amplifyではサービスの立ち上げをCloudFormationを使って実行されており、処理が完了するまで待ちます。 処理が完了したらAWSコンソールにアクセスしてCognitoのページをみるとこのようなものが作成されています。

これでバックエンドの準備は終わりました。早速、フロントエンドから認証画面が表示されるようにしてみましょう。

ログイン画面の表示

Amplifyで作成した環境とやりとりする時に便利なライブラリやコンポーネントが公式から配布されています。使用できるようにするために次のコマンドを実行してパッケージをインストールします。

npm install aws-amplify @aws-amplify/ui-react

今回もこれまでの記事でも使用しているプロジェクトを使用しています。

./src/app/page.tsxというファイルを./src/app/index.tsxにファイル名を変更して移動します。

各ページのコンポーネントに作用するように_app.tsxというファイルを作成します。 _app.tsxはNext.jsであらかじめ決められている機能です。このファイルを作成することで各ページに共通的な処理を実装したい場合に使います。

今回は、全てのページでログイン処理が行われて欲しいので、_app.tsxファイルに作成します。

./src/pages/_.app.tsxに次のコードを記述します。

import { Authenticator } from "@aws-amplify/ui-react";
import { Amplify } from "aws-amplify";
import type { AppProps } from "next/app";
import awsExports from "../src/aws-exports";
import "@aws-amplify/ui-react/styles.css";
import "./app.css"

Amplify.configure({ ...awsExports });

export default function App({ Component, pageProps }: AppProps) {
  return (
    <Authenticator.Provider>
      <Component {...pageProps} />
    </Authenticator.Provider>
  );
}

Amplify.configure({ ...awsExports });は、Amplifyの機能を使用するために必要な情報を読み込むための処理です。Amplifyを使用するためには必ず必要なものですので、おまじないとして記述してください。

<Authenticator.Provider> ... </Authenticator.Provider>は、認証機能のコンポーネントを使用できるようにするために必要なものです。

import "@aws-amplify/ui-react/styles.css";を使用していないと、スタイルが全く適用されていないログインフォームが表示されます。これを使用することでAmplifyが標準で提供しているスタイルを適用することができます。もちろん、カスタマイズしたい場合には独自で定義する方法もありますが、今回は割愛します。

これで_app.tsxファイルの編集は終了です。

次に./src/pages/index.tsxにログイン認証を追加してみましょう。 既存の処理を囲うように<Authenticator> ... </Authenticator>を追加します。

+ import { Authenticator } from "@aws-amplify/ui-react";
...
  return (
+   <Authenticator>
        {{ここに既存の処理}}
+   </Authenticator>
  );
...

ファイルの変更が終わったらアプリケーションを実行してみましょう。次のような画面が表示されたら成功です。

ユーザーの登録方法は、画面から作成してもよいですし、Cognito画面から追加してもどちらでも構いません。もし、画面から自由に登録させたくない場合には、設定によって無効化することもできます。

ログアウト

それでは、ログイン画面ができたところで、次はログアウト処理を実装してみましょう。 useAuthenticator()signOutを使います。この関数を呼び出すだけでログアウト処理が実行されます。

import {
  Authenticator,
+ useAuthenticator
} from "@aws-amplify/ui-react";
...
export default function Home() {
+ const { signOut } = useAuthenticator();
...
   return (
    <Authenticator>
      <div>
+      <button className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
+         onClick={signOut}
+       >
+         ログアウト
+      </button>
      </div>
    </div>
    </Authenticator>
  );
}

おわりに

シンプルなパターンですがログイン認証をつけることができました。 ログインの仕組みを1から作ろうとすると大変なことが多いですが、ここまで手軽に呼び出せるのはいいですね。 次回も引き続きAmplifyネタが続きます。