Vue.jsとAWS Amplifyで開発するサーバレスなWebアプリ:authコンポーネント
はじめに
前回の投稿でAWS Amplifyを利用したVue.jsの開発環境を構築しました。
今回はAWS Amplifyのauthを少し掘り下げます。
authを利用できれば認証を簡単に組み込むことができます。
authコンポーネント
aws-amplify-vueにはいくつかのコンポーネントが用意されています。
前回の投稿では amplify-authenticator と amplify-sign-out を利用しました。
amplify-authenticator
概要
amplify-authenticatorは認証に関する機能が用意されています。
このコンポーネントを呼び出すだけで一通りのことが実現できます。含まれているのは以下の機能です。
- サインアップ
- サインアップ確認
- サインイン確認
- サインイン
- パスワード再設定
<template> <amplify-authenticator :auth-config="authConfig" /> </template> <script> import { AmplifyEventBus } from 'aws-amplify-vue' import Auth from '@aws-amplify/auth' export default { props: [], data () { return { authConfig: { signInConfig: { header: 'サインイン' }, signUpConfig: { hideDefaults: true, signUpFields: [ { label: 'ユーザーID', key: 'username', required: true, type: 'email', displayOrder: 0 }, { label: 'パスワード', key: 'password', required: true, type: 'password', displayOrder: 1 } ] }, confirmSignUpConfig: {}, forgotPasswordConfig: {}, confirmSignInConfig: {} } } } } </script>
signUpConfig、signInConfigなどが各コンポーネントの設定情報です。
signUpConfigのsignUpFieldsにはサインアップ画面のフィールドを定義しています。
- label:フィールドのラベル
- key:フィールドの値とcognitoの属性値を紐づけています。
- required:必須か
- type:フィールドタイプ(type: 'text'とするとただのテキストフィールドになります)
- displayOrder:フィールドの表示順
詳しいドキュメントはこちらを参照してください。
イベント
各コンポーネントで発生するイベントはAmplifyEventBus経由で受け取ります。 リスナーを登録して適宜必要な処理を実装します。
AmplifyEventBus.$emit('authState', 'signedIn') はユーザーがサインインに成功したときに発生します。
前回のサンプルプログラムで実装したのは
- beforeCreateフック内でユーザー情報を取得する。
- 取得したユーザーのauthStateの値で処理を振り分ける
- signedInなら/photoへ移動する。
import { AmplifyEventBus } from 'aws-amplify-vue' import Auth from '@aws-amplify/auth' export default { props: [], data () { return { signedIn: false, // 〜 省略 〜 }, async beforeCreate () { try { await Auth.currentAuthenticatedUser() this.signedIn = true } catch (err) { console.log(err) this.signedIn = false } AmplifyEventBus.$on('authState', (info) => { if (info === 'signedIn') { this.signedIn = true this.$router.push('/photo') } else { this.signedIn = false } }) } }
amplify-sign-out
概要
amplify-sign-out はサインアウトする機能が用意されています。
<template> <amplify-sign-out /> </template> <script> import { AmplifyEventBus } from 'aws-amplify-vue' import Auth from '@aws-amplify/auth' export default { props: [], data () { // 〜 省略 〜 } } </script>
イベント
amplify-authenticatorと同様にAmplifyEventBus経由で受け取ります。
AmplifyEventBus.$emit('authState', 'signedOut') はユーザーがサインアウトに成功したときに発生します。
コンポーネントのUIカスタマイズ
英語のメッセージを日本語に変える
AWS Amplify I18nモジュールがあるため、そちらを使うことでメッセージを変更できます。
signOutButton: this.$Amplify.I18n.get('Sign Out')
各コンポーネント内で指定されたキーでメッセージを取得しているので、日本語用のメッセージを登録することでメッセージを日本語に変えられます。
amplify-sign-up
- signUpFields.label
- 説明:フィールドのラベル、プレースホルダー
- 備考:signUpFieldsのlabelをキーとして利用しています
- 'Create Account'
- 説明:アカウント作成ボタン
- 'Have an account? '
- 説明:アカウントはありますか?のラベル
- 'Sign in'
- 説明:サインインリンク
- 'Create a new account'
- 説明:サインアップ画面ヘッダー
- 備考:デフォルト値
amplify-sign-in
- 'Password'
- 説明:パスワード入力フィールドのラベル
- 'Enter your password'
- 説明:パスワード入力フィールドのプレースホルダー
- 'Forget your password? '
- 説明:パスワード再設定リンクのヒント
- 'Reset password'
- 説明:パスワード再設定リンク
- 'Sign In'
- 説明:サインインボタンのテキスト
- 'No account? '
- 説明:サインアップリンクのラベル
- 'Create account'
- 説明:サインアップリンク
- 'Sign in to your account'
- 説明:サインイン画面ヘッダー
- 備考:デフォルト値
amplify-confirm-sign-up
- 'Confirmation Code'
- 説明:確認コード入力のラベル
- 'Lost your code? '
- 説明:コード再送リンクのヒント
- 'Resend Code'
- 説明:コード再送リンクのテキスト
- 'Confirm'
- 説明:確認ボタンのテキスト
- 'Have an account? '
- 説明:アカウントはありますか?のラベル
- 'Back to Sign In'
- 説明:サインインに戻るリンクのテキスト
- 'Confirm Sign Up'
- 説明:サインアップ確認画面のヘッダー
amplify-sign-out
- 'Sign Out'
- 説明:サインアウトボタンのテキスト
- 備考:デフォルト値
これらのメッセージをmain.jsに設定する。
import Vue from 'vue' import './plugins/vuetify' import App from './App.vue' import router from './router' import store from './store' import Amplify, * as AmplifyModules from 'aws-amplify' import { AmplifyPlugin } from 'aws-amplify-vue' import awsconfig from './aws-exports' Amplify.configure(awsconfig) Vue.use(AmplifyPlugin, AmplifyModules) Vue.config.productionTip = false let messageResource = { ja:{ 'Create Account': '', 'Have an account? ': '', 'Sign in': '', 'Create a new account': '', 'Password': '', 'Enter your password': '', 'Forget your password? ': '', 'Reset password': '', 'No account? ': '', 'Create account': '', 'Sign in to your account': '', 'Sign Out': '' } } AmplifyModules.I18n.putVocabularies(messageResource) new Vue({ router, store, render: h => h(App) }).$mount('#app')
フィールドを追加する
サインアップ画面の入力フィールドにユーザ名とパスワード以外のフィールドを追加したいケースはあると思います。
signUpConfigのsignUpFieldsをカスタマイズすることで実現可能です。また、カスタム属性を追加することも可能です。
今回の例はカスタム属性を追加したケースです。
但し、issueに書いてありますが、今のamplify-cliでCognitoのカスタム属性の追加はできません。
ここだけ手作業が発生してしまいます。
amplify add auth amplify push
- pushしたのち、AWSのコンソールからCognitoの画面を開きます。
- ユーザープールの画面を開きます。
- カスタム属性としてtenantIdを追加します。
変更を保存します。カスタム属性に tenantId が追加されました。
signUpFieldにテナントIDを追加します。
signUpConfig: { signUpFields: [ { label: 'ユーザーID', key: 'username', required: true, type: 'email', displayOrder: 1 }, { label: 'パスワード', key: 'password', required: true, type: 'password', displayOrder: 2 } { label: 'テナントID', key: 'custom:tenantId', required: true, type: 'text', displayOrder: 0 } ] }
起動してサインアップ画面に移動するとテナントIDが入力フィールドとして追加されていることが確認できます。
サインアップしてユーザーを登録するときちんとカスタム属性に値が設定されています。
一部手作業が発生しますが、登録するユーザー情報にカスタム属性まで追加できることが確認できました。
まとめ
簡単なカスタマイズであれば可能ですが、全てが完璧という状態ではありませんでした。
自由度の高いカスタマイズを行うのであれば、自作のコンポーネントにAWS AmplifyのAPIを用いて制御する必要がありそうです。
ちなみにコンポーネントに対する要望や課題(UIだけに限らず)を受けてリファクタリングを検討しているようで、Issueはこちらです。2019年末にはリリースしたいようです。
次回はstorageコンポーネントについて試したいと思います。