aws-amplifyを利用してログイン画面を爆速で実装する .ver Vue.js

# はじめに

ログインって必要になること多いですよね？
でもログイン機能って実装するのめんどくさいですよね？
ログイン認証を実装したり、ログインユーザーのテーブル用意したり、ユーザー作成機能実装したり、パスワードリマインダーも必要になったり……うーん、めんどくさい。

そんなときにうってつけなのが、**AmazonCognito**です！
AWSを使っている人なら一度は聞いたことあるんじゃないでしょうか？
認証周りをよしなにやってくれるサーバレスなマネージドサービスです。
ログイン認証はもちろんのこと、ログインしたユーザーに対して、一時的に有効なTokenやCredentialを渡したりすることができます。
Cognitoを使うとログイン処理がすごく簡単に実装することができます。

## 画面作るのもめんどくさい…

Cognitoを使うとログイン処理が簡単に実装できるのはわかった。けど、**画面を作るのがめんどくさい…**
わかります。すごく気持ちわかります……
という方におすすめなのが、今回紹介する**AWS Amplify**です。

```
AWS Amplify は、AWS を使用したスケーラブルなモバイルアプリケーションの作成、設定、実装を容易にします。
Amplify はモバイルバックエンドをシームレスにプロビジョニングして管理し、バックエンドを iOS、Android、ウェブ、React Native のフロントエンドと
簡単に統合するためのシンプルなフレームワークを提供します。
また、Amplify は、フロントエンドとバックエンドの両方のアプリケーションリリースプロセスを自動化し、機能をより迅速に提供することができます。
```
引用元: ([https://aws.amazon.com/jp/amplify/](https://aws.amazon.com/jp/amplify/))

要するにモバイルアプリやWebアプリからAWSリソースを利用する際の処理を、簡潔にしてくれる便利アイテムみたいなものです。
今回はこのAmplifyのVue.js版である**aws-amplify-vue**を中心に話を進めていきます。

## 目的

`amplify-vue`を利用してログイン画面を**爆速**で実装する

## 前提

この記事ではVue.jsの`template`は`pug`、`script`は`TypeScript`、`style`は`scss`で書いています。

## 下準備

AmplifyにはCLIツールが用意されていて、ローカルからAWSリソースを作成することができます。
[この記事](https://qiita.com/is_ryo/items/b9feeb017366b0cee544)の手順1~4までしていただくと、CognitoがAWSにデプロイされます。

## amplify-vueのインストール

`npm` か `yarn` で `aws-amplify-vue` をインストールします。

```terminal
$ yarn add aws-amplify-vue
```

インストールできたら`main.ts`を書き換えます。

```ts:main.ts
import Vue from "vue";
import App from "./app/App.vue";
import router from "./router";
import store from "./store";
import "./registerServiceWorker";

import Amplify, * as AmplifyModules from "aws-amplify";
import { AmplifyPlugin } from "aws-amplify-vue";
import aws_exports from "./aws-exports";

Amplify.configure(aws_exports);
Vue.use(AmplifyPlugin, AmplifyModules);

Vue.config.productionTip = false;

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");
```

これで下準備は完了です。

## SignIn

こういう感じのフォームが用意されています。
![amplify_signin.png](https://qiita-image-store.s3.amazonaws.com/0/95875/0958a176-0c7b-31a3-fd23-ece54fcaa87d.png)

Vueファイルに書くソースコードはこんな感じ

```pug:template
.auth
  amplify-sign-in
```

## SignUp
こういう感じのフォームが用意されています。
![amplify_signup.png](https://qiita-image-store.s3.amazonaws.com/0/95875/607c0f8e-3225-3eb2-a9d3-e37491d0e10a.png)

Vueファイルに書くソースコードはこんな感じ

```pug:template
.auth
  amplify-sign-up(:signUpConfig="signUpConfig")
```

```ts:script
import { Component, Vue } from "vue-property-decorator";
import router from "@/router";

@Component({})
export default class Auth extends Vue {
  public signUpConfig = {
    hiddenDefaults: ["phone_number"]
  };
}
```
コンポーネントにpropで渡している`signUpConfig`はSignUpする際に必要となる項目の設定をすることができます。
上記のソースコードは`phone_number`(電話番号)をSignUpするのに必要ない項目としています。

## Confirm SignUp
こういう感じのフォームが用意されています。
![amplify_confirmsignup.png](https://qiita-image-store.s3.amazonaws.com/0/95875/64980751-3fb2-585f-6843-7a3a13886955.png)

Vueファイルに書くソースコードはこんな感じ

```pug:template
.auth
  amplify-confirm-sign-up
```

## Forgot Password
こういう感じのフォームが用意されています。
![amplify_forgot_password.png](https://qiita-image-store.s3.amazonaws.com/0/95875/41ce0253-ddc0-9559-0995-226f4ccf392c.png)

Vueファイルに書くソースコードはこんな感じ

```pug:template
.auth
  amplify-forgot-password
```

## SignOut
こういう感じのボタンが用意されています。
![amplify_signout.png](https://qiita-image-store.s3.amazonaws.com/0/95875/31418e7b-de8e-78e8-6320-c5f519553a16.png)

Vueファイルに書くソースコードはこんな感じ

```pug:template
.auth
  amplify-sign-out
```

## 各フォームの切り替え

`AmplifyEventBus`で各コンポーネントのイベント発生を検知することができます。
それを利用して各フォームを切り替えていきます。

```pug:template
.auth
  amplify-sign-in(v-if="displayMenu==='signIn'")
  amplify-sign-up(v-else-if="displayMenu==='signUp'", :signUpConfig="signUpConfig")
  amplify-confirm-sign-up(v-else-if="displayMenu==='confirmSignUp'")
  amplify-forgot-password(v-else-if="displayMenu==='forgotPassword'")
```

```ts:script
import { Component, Vue } from "vue-property-decorator";
import { AmplifyEventBus } from "aws-amplify-vue";
import router from "@/router";

@Component({})
export default class Auth extends Vue {
  public displayMenu: string = "signIn";
  public signUpConfig = {
    hiddenDefaults: ["phone_number"]
  };

  public created() {
    // `info` にどのイベントが発生したかが入ってくるので、フォームを切り替えたり、SignIn後の処理を書いたり…
    AmplifyEventBus.$on("authState", (info: string) => {
      console.log(info);
      if (info === "signedIn") {
        router.push("/");
      } else {
        this.displayMenu = (info === "signedOut") ? "signIn" : info;
      }
    });
  }
}
```

## さいごに

いかがでしたでしょうか？
ここまでだいたい2,30分もあれば実装できると思います。
「デザインにこだわらないから、とりあえずログイン機能を画面付きで実装したい」という方にはもってこいだと思います。
今回は触れていませんが、`aws-amplify`を使えば、デザイン懲りつつログイン処理の部分を完結に書くこともできます。
詳しくは[こちらの記事](https://qiita.com/is_ryo/items/b9feeb017366b0cee544)を参照してください。
ではまた！！！