amplify を使わずにNuxt3+cognitoで認証処理 


## 概要
```Cognito```のデフォルトログインページをNuxt3のプロジェクトに組み込みました。
```Amplify```を使わずに認証処理を簡単にしたかったのでその備忘録です。
※使わずに、と言いましたがnpmパッケージは使用します。

```Amplify```を使いたくなかった理由は、本格的に使用すると便利すぎて何でもできてしまい、頻繁に更新される```Amplify```の更新作業で地獄を見ることになりそうだったからです。そんなに深い意味はありません。
※一般的にパッケージの更新はしたほうがいいと思います。

## 開発環境
node：16.17.1
Nuxt： 3.0.0

## 実装手順

1. まず初めにNuxtのプロジェクトを用意する必要があります。
    ```nuxt3-cognito```の部分はプロジェクト名です。
    ```cmd
    npx nuxi init nuxt3-cognito
    cd ./nuxt3-cognito
    npm i
    ```

1. 必要なパッケージをインストールします。
    ```cmd
    npm i aws-amplify@5.0.4
    ```

1. 環境変数ファイルの設定と今後扱う変数の定義をします。
    
    ```typescript:.env
    AWS_REGION=ap-northeast-1
    USER_POOL_ID=ap-northeast-1_XXXXXXXXX
    USER_POOL_WEB_CLIENT_ID=XXXXXXXXXXXXXXXXXXXXXXXXXX
    COGNITO_DOMAIN_PREFIX=nuxt3-cognito
    APP_BASE_URL=http://localhost:3000
    ```
    - USER_POOL_ID
    - USER_POOL_WEB_CLIENT_ID


    は以下の赤枠AWS Cognitoから取得します。
    ![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527164/71e7627b-9fbb-30a7-5e6d-30d34ab3b613.png)
    ![キャ1チャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527164/f8840e6e-033f-6395-207f-632aaf1670be.png)


1. 作成した環境変数ファイルをNuxtで読み込みましょう

    ```typescript:nuxt.config.ts
    export default defineNuxtConfig({
      runtimeConfig: {
        public: {
          awsRegion: process.env.AWS_REGION,
          userPoolId: process.env.USER_POOL_ID,
          userPoolWebClientId: process.env.USER_POOL_WEB_CLIENT_ID,
          cognitoDomainPrefix: process.env.COGNITO_DOMAIN_PREFIX,
          appBaseUrl: process.env.APP_BASE_URL,
        },
      },
    }
    ```

1. Cognitoの設定ファイルを作成します。

    ```typescript:plugins/amplifyConfig.ts
    import { Amplify } from 'aws-amplify'
    import { defineNuxtPlugin } from '#app'
    
    export default defineNuxtPlugin(() => {
      const config = useRuntimeConfig() // 環境変数読み込み用
      const region = config.public.awsRegion
      const userPoolId = config.public.userPoolId
      const userPoolWebClientId = config.public.userPoolWebClientId
      const cognitoDomainPrefix = config.public.cognitoDomainPrefix
      const appBaseUrl = config.public.appBaseUrl
      const amplifyConfig = {
        Auth: {
          region,
          userPoolId,
          userPoolWebClientId,
          oauth: {
            domain: `${cognitoDomainPrefix}.auth.${region}.amazoncognito.com`,
            scope: ['openid'], // 認証成功時にどこまで情報を取得するか権限
            redirectSignIn: appBaseUrl, // ログイン成功時に遷移するURL
            responseType: 'code',
          },
        },
      }
      Amplify.configure(amplifyConfig)
    })
    ```

1. 前の手順で作成したCognitoの設定ファイルをNuxtで読み込みます。
    ```typescript:nuxt.config.ts
    export default defineNuxtConfig({
      plugins: [{ src: '@/plugins/cognitoConfig.ts' }],  // 追加
      runtimeConfig: {
        public: {
          awsRegion: process.env.AWS_REGION,
          userPoolId: process.env.USER_POOL_ID,
          userPoolWebClientId: process.env.USER_POOL_WEB_CLIENT_ID,
          cognitoDomainPrefix: process.env.COGNITO_DOMAIN_PREFIX,
          appBaseUrl: process.env.APP_BASE_URL,
        },
      },
    }
    ```

1. ページ遷移するたびにCognito認証をするmiddlewareを作成します。

    ```typescript:middleware/authenticated.ts
    import { Auth } from '@aws-amplify/auth'
    
    /** 認証を確認し、無効の場合にサインイン画面へ遷移 */
    export default defineNuxtRouteMiddleware(async () => {
      try {
        await Auth.currentAuthenticatedUser()
      } catch (error) {
        await Auth.federatedSignIn()
      }
    })
    ```

1. 前の手順で作成したmiddlewareをindex.vueに適応し、遷移ごとに発火するよう設定しましょう
    ```typescript:index.vue
    ...
    <script setup lang="ts">
    definePageMeta({
      middleware: ['authenticated'],
    })
    </script>
    ```



## まとめ

備忘録ということでかなり簡単に書いてしまいました…
何か間違いがあったらご指摘ください。

## 参考
[Nuxt公式ページ](https://nuxt.com/)
[AmplifyでCognitoのHosted UIを利用した認証を最低限の実装で動かしてみて動作を理解する](https://dev.classmethod.jp/articles/learn-authentication-using-cognitos-hosted-ui-with-amplify/)