Fusic Tech Blog

Fusion of Society, IT and Culture

Nuxt.js+AWS Amplify+Cognitoでログイン認証する
2019/07/08

Nuxt.js+AWS Amplify+Cognitoでログイン認証する

ログイン認証の仕組みはセキュリティ上重要であるにも関わらず、実装に手間がかかる部分です。

普段はRuby on Railsを使ってシステム開発しているのでdeviseに頼りっきりになってしまっていて 他言語やフレームワークが変わると最初の壁になる実装でもあります。

最近はNuxt.jsに可能性を感じているので、Nuxt.jsでのログイン認証を実装してみました。 とはいえ1から実装するのは非効率かつリスクが大きいので、AWS Amplify+Cognitoで簡単に実装できないか試してみることにしました。

前提

  • AWS CLI, Amplify CLIが既にインストールされていること
  • Nuxt.jsでSSRは無効とすること
  • AWS CLIでAWSへアクセスできる状態であれば、AWSコンソールへログインする必要は無い

Nuxt.jsのプロジェクトを作成

create nuxt-appを使って、シンプルなNuxt.jsのプロジェクトを作成します。

$ yarn create nuxt-app cognito-auth
? Project name cognito-auth
? Project description My super-duper Nuxt.js project
? Author name Yuhei Okazaki
? Choose the package manager Yarn
? Choose UI framework Vuetify.js
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules Axios, Progressive Web App (PWA) Support
? Choose linting tools ESLint
? Choose test framework Jest
? Choose rendering mode Single Page App

AWS Amplifyの設定

aws-amplifyaws-amplify-vue をインストールします。 インストール後、Amplify CLIでinitしてAWS上にリソースを生成します。

Source Directory Path. としておきました。

$ yarn add aws-amplify
$ yarn add aws-amplify-vue

$ amplify init
? Enter a name for the project cognito-auth
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using none
? Source Directory Path:  .
? Distribution Directory Path: dist
? Build Command:  yarn build
? Start Command: yarn start
? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default

$ amplify add auth
 Do you want to use the default authentication and security configuration? Default configuration
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in when using your Cognito User Pool? Email
 Warning: you will not be able to edit these selections. 
 What attributes are required for signing up?

$ amplify push

pluginの追加

AWS Amplifyを読み込み・初期化するpluginを作成します。

plugins/amplify.js を作成します。

import Vue from 'vue'
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)

pluginを作成したら、 nuxt.config.js で読み込みます。

// ・・・中略・・・
  plugins: [
    {
      src: '~plugins/amplify.js',
      ssr: false
    }
  ],
// ・・・中略・・・

middlewareの追加

ログインが必要なページに非ログイン状態でアクセスした場合、 /signin へリダイレクトさせます。 Nuxt.jsの場合、このような制御は middleware で行うようです。

middleware/auth.js を作成します。

import { Auth } from 'aws-amplify'

export default async ({ redirect }) => {
  let signedIn = false
  await Auth.currentUserInfo()
    .then(data => (signedIn = Boolean(data)))
    .then(() => signedIn || redirect('/signin'))
}

ログインが必要なページでmiddlewareを使用するよう宣言します。
今回は pages/index.vue をログイン時にのみ閲覧可能とします。

// ・・・中略・・・

<script>
import Logo from '~/components/Logo.vue'
import VuetifyLogo from '~/components/VuetifyLogo.vue'

export default {
  components: {
    Logo,
    VuetifyLogo
  },
  middleware: 'auth'
}
</script>

Vueコンポーネントの編集

signinページを追加します。AWS Amplifyでコンポーネントが提供されているので非常に楽です。 pages/signin.vue を作成します。

<template>
  <amplify-authenticator />
</template>

ログイン/ログアウト時にページ遷移させる制御を layout/default.vue へ追加します。

<script>
import { AmplifyEventBus } from 'aws-amplify-vue'

// ・・・中略・・・

export default {

// ・・・中略・・・

  created() {
    AmplifyEventBus.$on('authState', (info) => {
      if (info === 'signedIn') {
        this.$router.push('/')
      } else if (info === 'signedOut') {
        this.$router.push('/signin')
      }
    })
  }
}
</script>

新規登録〜ログイン

メールアドレス等を入力して新規登録できます。デフォルトでConfirmationも付いているので良いですね。

感想

  • pluginやmiddlewareの実装が必要な点が手間でした。誰かmodule化してくれないだろうか・・・
  • AWS Amplifyを今回初めて使用しましたが、認証関連の画面が一通りコンポーネントとして提供されておりとても便利でした
  • AWS Amplifyは認証に限らず他のサーバレスなサービスとも連携が可能なので、これらも一度使ってみようと思います

yuuu

yuuu

2018年の年明けに組込み畑からやってきた、2児の父 兼 Webエンジニアです。 業務ではRuby on Rails、最近ではフロントエンドにVue.jsを使っています。趣味でGo言語を触ることも。 Lab.Consoleのプロダクトオーナーをしており、AWSと仲良くなれるよう日々勉強中です。