NuxtJS×Amplifyで独自ログイン画面によるログイン機能を実装


Amplifyを使ったシンプルな実装例が意外となかったので書いてみました。
コードは最小限で実装しているので分かりやすいと思います。

ソースコードは[こちら](https://github.com/syoppylife/nuxt-amplify-signin-example)

- まずはAWSのコンソールからCognitoの設定を行います
    - サービス一覧からAmazon Cognitoを選びユーザープールの管理をクリックします。
        - ユーザープールを作成をクリックし、任意の名前を付けたらデフォルトを確認するをクリックします。
        - 特に何も変更せずにプールの作成をクリックします。

    - 続けて左のメニューのユーザーとグループをクリックし、ユーザーの作成ボタンをクリックします
        - 仮パスワードは後で使うので忘れないようにメモしておいてください。
    ![スクリーンショット 2021-08-13 2.00.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74780/35cfc387-87a4-b52e-7c35-2c51b59f3079.png)


- 次は左のメニューのアプリクライアントをクリックし、***以下の設定*** にてアプリクライアントの作成ボタンをクリックします
    - 名前は好きな名前で問題ありません。
![スクリーンショット 2021-08-13 1.46.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74780/c5009875-9573-f0b5-10ea-36270c196029.png)


- Awsコンソールの設定は以上です。続いてNuxtJSのアプリを作成します。
    - 公式ドキュメントの内容に沿ってcreate-nuxt-appを実行します
![スクリーンショット 2021-08-13 0.00.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74780/207c7567-12d2-fe42-eea7-c85aef6863b9.png)
    - 一度ローカルサーバーを起動して動くことを確認した後components/Tutorial.vueを以下の通り雑に改修します。

```components/Tutorial.vue
<template>
  <div>
    email：<input v-model="email">
    pass：<input v-model="password" type="password">
    <button @click="login">ログイン</button>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  data: () => ({
    email: '' as string,
    password: '' as string,
  }),
  head() {
    return {
      title: 'ログイン',
    }
  },
  methods: {
    login() {
      console.log(this.email)
      console.log(this.password)
    },
  },
})
</script>
```


![スクリーンショット 2021-08-13 0.17.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74780/f37e8e48-db6a-d574-258f-b8c4a7e02674.png)

- Amplifyのライブラリをインストールします
    - 他の方の記事などではAmplify Coreを使ったやり方が多かったですが、ログインするだけならAmplify Authだけで十分です。

```
npm i @aws-amplify/auth
```

  - 認証用のプラグインを作成します。
     - userPoolIdなどは環境変数で指定することを推奨しますが、ここでは直接設定します。

```
% mkdir plugins           
% touch plugins/amplify.ts
```


```plugins/amplify.ts
import Auth from '@aws-amplify/auth';

export default () => {
  Auth.configure({
    Auth: {
      region: 'ap-northeast-1',
      userPoolId: 'AWSコンソール：ユーザープールの全般設定を確認',
      userPoolWebClientId: 'AWSコンソール：ユーザープールのアプリクライアントを確認',
    },
  })
}
```

  - nuxt.config.jsにプラグインの設定を追記します
 
```nuxt.config.js
  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
    '~/plugins/amplify'
  ],
```

- ログイン画面を改修します

```components/Tutorial.vue
<template>
〜 省略（変更ナシ）〜
</template>

<script lang="ts">
import Vue from 'vue'
import Auth from '@aws-amplify/auth'

export default Vue.extend({
  〜 省略（変更ナシ）〜
  methods: {
    async login() {
      console.log(this.email)
      console.log(this.password)
      await Auth.signIn(this.email, this.password)
        .then(response => {
          console.log(response.signInUserSession.accessToken.jwtToken)
          console.log(response.signInUserSession.idToken.jwtToken)
        })
        .catch(() => {
          console.error('ログイン失敗')
        })
    },
  },
})
</script>

```

- 先ほど作成したユーザーはステータスがFORCE_CHANGE_PASSWORDになっているのでCLIでステータを変更します
    - AWS CLIが入ってない方はbrewなどでインストールしてください。

```
% aws cognito-idp admin-initiate-auth \
--user-pool-id ユーザープールの全般設定を確認 \
--client-id ユーザープールのアプリクライアントを確認 \
--auth-flow ADMIN_NO_SRP_AUTH \
--auth-parameters \
USERNAME=ユーザー名,PASSWORD=AWSコンソールで指定した仮パスワード

```


- ターミナルにsessionが表示されるので続けて以下を実行します。


```
% aws cognito-idp admin-respond-to-auth-challenge \
--user-pool-id ユーザープールの全般設定を確認 \
--client-id ユーザープールのアプリクライアントを確認 \
--challenge-name NEW_PASSWORD_REQUIRED \
--challenge-responses 'NEW_PASSWORD=任意のパスワード,USERNAME=AWSコンソールで指定したユーザー名' \
--session "コンソールで表示されたセッションの値（実際はかなり長いです）"
```

![スクリーンショット 2021-08-12 23.49.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74780/cd246601-0956-259a-2970-ed77f1b050cf.png)

![スクリーンショット 2021-08-13 2.24.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74780/636b5a38-2550-f036-7ed2-3f9f039783b8.png)

- このようにブラウザのコンソールにjwtTokenが表示されればログイン成功です。
![スクリーンショット 2021-08-13 2.40.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74780/227c0a19-c446-60f5-1d29-8db2d2f3c189.png)