Nuxt3 (vite)にAmplifyを導入するまでにやったこと

Amplifyを導入する為に必要な @aws-amplify/cli をインストール後、必要な設定を行います。

# amplifyを利用する為のCLIを導入
npm install -g @aws-amplify/cli 

# amplifyを利用する為のAWSアカウント設定
amplify configure

# amplifyのアプリケーションを作成
amplify init

プラグインの設置

Amplifyの設定を読み込む為のpluginsファイルを追加します。

src/plugins/amplify.ts

import { defineNuxtPlugin } from '#app'
import amplifyConfig from '../aws-exports'
import { Amplify } from '@aws-amplify/core'

export default defineNuxtPlugin(() => {
  Amplify.configure(amplifyConfig)
})

仮会員登録

会員登録用のフォームからユーザ名とパスワードを入力すると仮会員登録の状態となり入力されたメールアドレスに承認用のURLが記載されたメールが送信されます。

async signUp(name: string, email: string, password: string): boolean {
    try {
      const user = await Auth.signUp(email, password)
      if (user) {
        const input = {
          userSub: user.userSub,
          fullName: name,
          profileImageFileName: '',
        }
        this.useAuthTypeApiKey()
        await API.graphql(graphqlOperation(createUser, { input }))
        return true
      }
    } catch (error) {
      console.log('error signup in', error)
      if ((error as string).match(/UsernameExistsException/)) {
        alert(
          '既に会員登録されています。認証済みでない場合はメールを確認してください。'
        )
      }
      return false
    }
  }

仮会員登録後の認証

送信されてきたメールに記載の認証チェック用URLをクリックすると、認証コードを入力する画面が表示されるので、入力されたメールアドレスと認証コードから仮会員のユーザを検証します。

async confirmRegistration(
    email: string,
    verificationCode: string
  ): Promise<boolean> {
    try {
      const result = await Auth.confirmSignUp(email, verificationCode)
      if (result !== 'SUCCESS') {
        new Error('メールアドレス検証に失敗しました')
      }

      // NOTE: デフォルトの挙動だと検証する前にメールアドレスを変更してしまうので、
      // その対応としてcustome:verified_emailに古いメアドを指定する。詳しくは以下のリンクを参照。
      // https://zenn.dev/dove/articles/78ecf08b51ee0c

      // 上記対応をしないのであればこの処理は不要
      const user = await Auth.currentAuthenticatedUser()
      await Auth.updateUserAttributes(user, {
        email, // ここと
        'custom:verified_email': email, // ここに新しいメールアドレスをいれる。
      })

      return true
    } catch (error) {
      console.log('error signup in', error)
      if ((error as string).match(/UsernameExistsException/)) {
        alert(
          '既に会員登録されています。認証済みでない場合はメールを確認してください。'
        )
      }
      return false
    }
  }

ログイン

検証された会員のメールアドレスとパスワードでサインインを行うとトークンを取得することができます。パーソナルのデータ取得や更新・削除はこのトークンを利用してアクセスします。

async signIn(email: string, password: string): Promise<boolean> {
    try {
      const user = await Auth.signIn(email, password)
      if (user) {
        this.useAuthTypeApiKey()
        const userData = await API.graphql(
          graphqlOperation(getUser, { userSub: user.username })
        )
        const { id, fullName } = userData.data.listUsers.items[0]
        this.id = id
        this.name = fullName
        this.token = await this.getJwtToken()
        return true
      }
      return false
    } catch (error) {
      console.log('error signing in', error)
      alert('メールアドレスまたはパスワードが違います')
      return false
    }
  }

ログアウト

async signOut(): Promise<boolean> {
    try {
      await Auth.signOut()
      this.id = undefined
      this.name = ''
      this.token = ''
      return true
    } catch (error) {
      console.log('error signing out', error)
      return false
    }
  }

npm run dev した際に以下のエラーが発生する場合は、SSRをOFFに設定することで回避できました。

WARN [SSR] Error transforming /root/study/amplify-nuxt3-sample/node_modules/nuxt/dist/pages/runtime/router.mjs: Parse failure: Unexpected token (69:4)

画面描画した際に以下のエラーが発生する場合は、global 変数をグローバルに参照できるようにすることで回避できました。

ReferenceError: global is not defined at node_modules/buffer/index.js

npm run buildした際に下記のエラーが発生する場合は、runtimeConfig のエイリアスを設定することで回避できました。

ERROR 'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-node/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js

nuxt.config.ts

const nuxtConfig = defineNuxtConfig({
  ssr: false, // ← Amplifyを利用する場合はSSRをOFFに設定する
  target: 'static',
  
  ・・・

	vite: {
	    define: {
	      global: {}, // ← global変数の参照エラーを回避する(Buildの際には逆にここをコメントアウトする必要がある・・)
	    },
	    resolve: {
	      alias: {
	        './runtimeConfig': './runtimeConfig.browser',
	      },
	    },
	  }

})

Nuxt3ではなく、Vue3を利用する場合は、index.html で global変数を用意してあげる

<script>
  if (global === undefined) {
    var global = window;
  }
</script>

Storybook を利用する場合は、@nuxt/storybook が、Nuxt3 に対応できていないため、@storybook/vue3 を利用します

.storybook/preview-head.html に global変数を用意してあげることで表示できるようになりました。

<!-- <https://github.com/aws/aws-amplify/issues/678> fix: -->
<script>
    if (global === undefined) {
        var global = window;
    }
</script>
<!-- <https://github.com/aws/aws-amplify/issues/678> fix end-->

コメントを残す

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。