はじめに
皆さん。こんにちは! DreamHanksのエルムです。
今回はAWS Amplifyの認証UIを簡単にカスタマイズする方法について説明していきます。
amplifyのインストール方法
Amplifyは、AWSが提供するフレームワークです。はじめに、AmplifyのCLIをインストールして設定する必要があります。
1 |
npm install -g @aws-amplify/cli |
AWS CLIをインストール・設定していない場合は、Amplify CLIを設定する必要があります。すでにAWS CLIを設定している場合は、AmplifyのCLIも設定する必要はありません。
1 2 |
# AWS CLIを持っていない場合は、このconfigureのみを実行してください。 $ amplify configure |
Amplify CLIがインストールされると、モバイルやウェブアプリケーションにモジュールを追加することができます。
それでは、Reactウェブアプリケーション用のAmplifyの初期設定と構成を行います。
Amplifyの初期化
CLIがグローバルにインストールされたので、1つのコマンドラインコールでReactアプリの中でAmplifyを初期化することができます。
1 2 |
# アプリケーションのルートディレクトリから実行してください。 $ amplify init |
このコマンドは、AWSの設定を初期化し、アプリケーションのルートに設定ファイルを作成します。
このコマンドは、AWSアカウントのサービスをプロビジョニングするものではありませんが、プロビジョニングを行うための基礎を作ります。
アプリケーションに認証を追加する方法
アプリケーションでフレームワークを初期化したので、モジュールの追加を始めましょう。今回のブログ記事では、アプリケーションに認証モジュールを追加します。
これは、コマンドラインで別の呼び出しを行うことで実現できます。
1 |
$ amplify add auth |
このコマンドでは、一連の質問を行います。各質問では、アプリケーションの認証を設定します。どのような設定が必要なのかわからない場合は、最初の質問で「Yes, use the default configuration」を選択してください。これらの設定は、amplify update authコマンドを実行することで、いつでも再設定することができます。
これで、アプリケーションに認証モジュールが設定されました。しかし、この設定をAWSアカウントにデプロイする必要があります。幸運なことに、この作業はAmplify CLIでも行うことができます。
1 |
$ amplify push |
これにより、認証モジュールをサポートするために必要なAWSアカウントの変更が作成され、デプロイされます。デフォルトの設定では、アプリケーションへの認証を処理するためにAWS Cognitoをプロビジョニングします。
デプロイが完了すると、ソースディレクトリに aws-exports.js という新しいファイルができます。このファイルは、AmplifyプロジェクトをサポートするためのAWSアカウント内のインフラを表しています。
AmplifyをReactで使用する方法
Amplifyフレームワークが追加され、認証を設定し、アプリケーションをサポートするために必要なAWSサービスをプロビジョニングしました。今度は、React/Gatsbyアプリケーションにフレームワークを活用するための設定を行います。
このブログ記事では、アプリケーションの主要なエントリーポイントであるAppコンポーネントを想定しています。また、最初に認証を受けなければ、アプリケーションにアクセスできないものとします。
ここでは、初期のAppコンポーネントをご紹介します。Gatsbyの設定により、/appルートで提供されています。今のところ、世界に向けて広く公開されており、認証は必要ありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import React from 'react' class App extends React.Component { constructor(props, context) { super(props, context) } render() { return ( <div> <h1>DreamHanks App</h1> </div> ) } } export default App |
今度は、Amplifyで追加した認証モジュールの後ろにアプリケーションを配置したいと思います。そのために、プロジェクトに2つのライブラリを追加します。
1 |
$ npm install aws-amplify aws-amplify-react |
この2つのライブラリを追加したので、アプリケーションに認証機能を追加することができます。まず、Appコンポーネント内でAmplifyを設定する必要があります。そして、Reactアプリケーション用に作成された高次コンポーネント(HOC)のwithAuthenticatorを使用します。このコンポーネントは、Appコンポーネントを認証の背後に置くためのすべてのロジックを追加します。また、ユーザーのログイン、新規ユーザーの登録、アカウントの確認やパスワードの再設定などのフローを処理するために必要なすべてのUIパーツも含まれています。
この変更がAppコンポーネントでどのように見えるかを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import React from 'react' import Amplify from 'aws-amplify' import {withAuthenticator} from 'aws-amplify-react' import config from '../../aws-exports' Amplify.configure(config) class App extends React.Component { constructor(props, context) { super(props, context) } render() { return ( <div> <h1>DreamHanks App</h1> </div> ) } } export default withAuthenticator(App, true) |
いくつかのコマンドライン操作で、アプリケーションに認証が組み込まれています。アプリケーションをサポートするために必要なすべてのAWSサービスは、Amplify Frameworkによってプロビジョニングされ、継続的にメンテナンスされます。
これは素晴らしいことですが、Parlerでは、Amplifyが提供するUIパーツをカスタマイズする機能も必要でした。事前に設定されたUIコンポーネントは使い始めには最適ですが、Tailwind CSSを使って自分のスタイルを加えたいと思いました。
それでは、SignInのようなデフォルトのコンポーネントを独自のCustomSignInコンポーネントでオーバーライドして、Amplifyの認証UIをカスタマイズする方法を探ってみましょう。
Amplify認証のUIをカスタマイズする方法
Amplify認証モジュールのlook and feelをカスタマイズするためには、変更したいUI部分に独自のコンポーネントを定義する必要があります。
次に行うのは、AmplifyのSignInコンポーネントを拡張した独自のコンポーネント、CustomSignInの定義です。これにより、親コンポーネントにすでに組み込まれているロジックをすべて使用しつつ、独自のUIを定義することができます。それでは、CustomSignInがどのようなものか見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
import React from 'react' import {SignIn} from 'aws-amplify-react' export class CustomSignIn extends SignIn { constructor(props) { super(props) this._validAuthStates = ['signIn', 'signedOut', 'signedUp'] } showComponent(theme) { return ( <div className="mx-auto w-full max-w-xs"> <form className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"> <div className="mb-4"> <label className="block text-grey-darker text-sm font-bold mb-2" htmlFor="username"> ユーザー名 </label> <input className="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight focus:outline-none focus:shadow-outline" id="username" key="username" name="username" onChange={this.handleInputChange} type="text" placeholder="ユーザー名を入力" /> </div> <div className="mb-6"> <label className="block text-grey-darker text-sm font-bold mb-2" htmlFor="password"> パスワード </label> <input className="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker mb-3 leading-tight focus:outline-none focus:shadow-outline" id="password" key="password" name="password" onChange={this.handleInputChange} type="password" placeholder="******************" /> <p className="text-grey-dark text-xs"> パスワードをお忘れですか?{' '} <a className="text-indigo cursor-pointer hover:text-indigo-darker" onClick={() => super.changeState('forgotPassword')} > パスワードをリセット </a> </p> </div> <div className="flex items-center justify-between"> <button className="bg-blue hover:bg-blue-dark text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" type="button" onClick={() => super.signIn()} > ログイン </button> <p className="text-grey-dark text-xs"> アカウントが未登録ですか?{' '} <a className="text-indigo cursor-pointer hover:text-indigo-darker" onClick={() => super.changeState('signUp')} > アカウントを作成 </a> </p> </div> </form> </div> ) } } |
CustomSignInでは、aws-amplify-reactのSignInコンポーネントを拡張しています。これは、showComponentメソッドをオーバーライドしつつ、changeStateやsignInなどの親クラスの機能を利用できるようにするためです。
renderメソッドをオーバーライドするのではなく、showComponentをオーバーライドしていることに注目してください。これは、親のSignInコンポーネントが、この関数の中でUIを定義しているからです。したがって、UIを表示するためには、コンポーネントでオーバーライドする必要があります。
コンストラクタの内部には次のような記述があります。
1 |
this._validAuthStates = ['signIn', 'signedOut', 'signedUp'] |
AmplifyはauthStateを使って、現在どの認証状態が有効かを追跡します。私たちが定義したカスタムコンポーネントは、このコンポーネントに対してどの認証状態が有効であるかを示すことができます。今回はログイン/サインインビューなので、authStateがsignIn、signedOut、signedUpのいずれかに該当する場合にのみ、カスタムUIを表示したいと思います。以上で、Amplifyが提供するデフォルトのUIに加えて、私たちのUIを表示するためのマジックソースが完成しました。
SignInコンポーネントを拡張し、showComponent関数をオーバーライドして、authStateをチェックし、その状態が求めているものであればUIを表示します。
カスタムUIを少し見てみると、「アカウント作成」ボタンがクリックされたときにsuper.changeState(“signUp”)を呼び出しています。これは、私たちが拡張している親コンポーネントで定義されている関数です。authStateがsignUpに更新され、SignUpコンポーネントがレンダリングされます。もちろん、CustomSignInを作成したときと同じ手順で、このコンポーネントをカスタマイズすることもできます。
他に必要な変更は、Appコンポーネントに戻ることだけです。Amplifyが提供するwithAuthenticator HOCを使う代わりに、Authenticatorコンポーネントを直接使うことにします。
ここでは、App コンポーネントをラップし、Authenticator コンポーネントを直接使用する AppWithAuth という新しいコンポーネントを定義することにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import React from 'react' import {SignIn} from 'aws-amplify-react' import config from '../../aws-exports' import {CustomSignIn} from '../Login' import App from '../App' import {Authenticator} from 'aws-amplify-react/dist/Auth' class AppWithAuth extends React.Component { constructor(props, context) { super(props, context) } render() { return ( <div> <Authenticator hide={[SignIn]} amplifyConfig={config}> <CustomSignIn /> <App /> </Authenticator> </div> ) } } export default AppWithAuth |
Appコンポーネントは、他のコンポーネントと同様に、renderメソッドの中でauthStateを受け取ります。このメソッドの中で状態をチェックすれば、サインインしたときにだけAppコンポーネントを表示することができます。
それでは、新しいAppコンポーネントのコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import React from 'react' class App extends React.Component { constructor(props, context) { super(props, context) } render() { if (this.props.authState == 'signedIn') { return ( <div> <h1>DreamHanks App</h1> </div> ) } else { return null } } } export default App |
このAppコンポーネントは非常にシンプルです。実際、ここでのAmplifyの概念は、このコンポーネントをレンダリングすべきかどうかを決定するauthStateのチェックだけです。
以上のようにして、Amplify Frameworkを使ってアプリケーションに認証機能を追加しました。また、Amplifyのコンポーネントをカスタマイズして、必要に応じて独自のルック、フィール、ロジックを提供しています。
終わりに
今回の記事は以上になります。
ご覧いただきありがとうございます。
コメント