dayjournal memo

Total 974 articles!!

Try #024 – AWS AmplifyとVue.jsでログイン機能を構築してみた

Yasunori Kirimoto's avatar

画像


画像




画像




AWS AmplifyとVue.jsでログイン機能を構築してみました!



事前準備


全体の構成はできるだけシンプルに。

バックエンド - ユーザー管理

  • Amazon Cognito

フロントエンド - ログイン機能

  • AWS Amplify
  • Vue.js


バックエンド


まずは、バックエンドを構築していきます。

今までは、Amazon Cognito等のサービスも自分で設定する必要があり設定だけでも苦労したのですが、AWS Amplify CLIが登場したことにより、コマンドのみでほぼ設定が完了することが可能なりました。


認証機能をのみであればこの2コマンドで実装可能です!

amplify add auth

画像


amplify push

画像


これでバックエンドの構築は完了になります。



フロントエンド


次に、フロントエンドを構築していきます。


実行環境

node v12.7.0
npm v6.10.0


まず、プロジェクトに必要なパッケージを2つインストールします。

npm install aws-amplify

画像


npm install aws-amplify-vue

画像



最後に、実際にログイン機能のコードを記述していきます。

基本的には、router.jsに認証部分のコードを記述し、UIは既にあるコンポーネントを指定することでそのまま表示することが可能です。


全体構成

画像


package.json

{
  "name": "amplify_prj",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "aws-amplify": "^1.1.32",
    "aws-amplify-vue": "^0.2.13",
    "bootstrap-vue": "^2.0.0-rc.19",
    "core-js": "^2.6.5",
    "vue": "^2.6.10",
    "vue-router": "^3.0.3",
    "vuex": "^3.0.1"
  },
  "devDependencies": {
    "@babel/polyfill": "^7.4.4",
    "@vue/cli-plugin-babel": "^3.8.0",
    "@vue/cli-plugin-eslint": "^3.8.0",
    "@vue/cli-service": "^3.8.0",
    "babel-eslint": "^10.0.1",
    "bootstrap": "^4.3.1",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "mutationobserver-shim": "^0.3.3",
    "node-sass": "^4.12.0",
    "popper.js": "^1.15.0",
    "portal-vue": "^2.1.4",
    "sass-loader": "^7.1.0",
    "vue-cli-plugin-bootstrap-vue": "^0.4.0",
    "vue-template-compiler": "^2.6.10"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}


/src


main.js

import '@babel/polyfill'
import 'mutationobserver-shim'
import Vue from 'vue'
import './plugins/bootstrap-vue'
import App from './App.vue'
import router from './router'
import store from './store'

// Amplify読み込み
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)


Vue.config.productionTip = false

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


store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        user: null
    },
    mutations: {
        // ユーザー情報保存
        setUser(state, user) {
            state.user = user
        },
    }
});

export default store


router.js

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import Login from './views/Login.vue'

import store from './store'

// Amplify読み込み
import { components, AmplifyEventBus } from 'aws-amplify-vue'
import Amplify, * as AmplifyModules from 'aws-amplify'
import { AmplifyPlugin } from 'aws-amplify-vue'

Vue.use(Router)
Vue.use(AmplifyPlugin, AmplifyModules)


let user;

// ユーザー管理
getUser().then((user) => {
    if (user) {
        router.push({path: '/'});
    }
});

function getUser() {
    return Vue.prototype.$Amplify.Auth.currentAuthenticatedUser().then((data) => {
        if (data && data.signInUserSession) {
            store.commit('setUser', data);
            return data;
        }
    }).catch(() => {
        store.commit('setUser', null);
        return null;
    });
}

// ログイン状態管理
AmplifyEventBus.$on('authState', async (state) => {
    if (state === 'signedOut'){
        user = null;
        store.commit('setUser', null);
        router.push({path: '/login'});
    } else if (state === 'signedIn') {
        user = await getUser();
        router.push({path: '/'});
    }
});

// ルーティング設定
const router = new Router({
    mode: 'history',
    routes: [
        {
            // ログインページ
            path: '/login',
            name: 'login',
            component: Login
        },
        {
            // トップページ
            path: '/',
            name: 'home',
            component: Home,
            meta: { requiresAuth: true}
        }
    ]
});

// リダイレクト設定
router.beforeResolve(async (to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        user = await getUser();
        if (!user) {
            return next({
                path: '/login'
            });
        }
        return next()
    }
    return next()
});

export default router


src/views


Home.vue

<template>
    <div class="home">
        <h1>ログイン済</h1>
        <hr>
        <Button name='sample'/>
        <hr>
        <!--ログアウトコンポーネント-->
        <amplify-sign-out></amplify-sign-out>
    </div>
</template>

<script>
    import Button from '@/components/Button.vue'

    export default {
        name: 'home',
        components: {
            Button
        }
    }
</script>


Login.vue

<template>
    <div class="login">
        <!--ログインコンポーネント-->
        <amplify-authenticator></amplify-authenticator>
    </div>
</template>

<script>
    export default {
        name: 'login'
    }
</script>


簡易ローカルサーバーで確認

npm run serve


ローカルサーバーを立ち上げて、ログイン画面でユーザーを登録しログインしてみます。

画像



AWSのコンソールを確認するとユーザーも正常に登録さています。

画像




AWS AmplifyとVue.jsを利用することで、手軽にログイン機能の構築ができました!

AWS Amplify CLIが登場したことにより、Amplifyを利用する場合に以前よりサーバーレス設定周りがめちゃくちゃ便利になったのでおすすめです。



Vue.jsについて、他にも記事を書いています。よろしければぜひ。
tags - Vue.js



book

Q&A