vue.jsとamplifyで、ユーザ認証のページ(ログイン・ログアウト)を作って、Web公開する。
最初のvue createで Manually select features を選んで、vue-routerとvuexを選択
あとは、ひたすらENTER連打でOK!
1, vueプロジェクト生成(フロント用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
node -v v14.2.0 npm -v 6.14.8 vue --version zsh: command not found: vue npm install -g @vue/cli vue --version @vue/cli 4.5.7 # vueプロジェクト生成(フロント用) vue create test ? Please pick a preset: Default ([Vue 2] babel, eslint) Default (Vue 3 Preview) ([Vue 3] babel, eslint) > Manually select features ? Check the features needed for your project: (*) Choose Vue version (*) Babel ( ) TypeScript ( ) Progressive Web App (PWA) Support (*) Router >(*) Vuex ( ) CSS Pre-processors (*) Linter / Formatter ( ) Unit Testing ( ) E2E Testing # ローカルで、vue.jsの動作確認 cd test yarn serve # ブラウザで確認したら、ctrl+cで中断する。 # amplify用のvueパッケージをインスト npm i aws-amplify aws-amplify-vue |
2, amplifyプロジェクト作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# amplifyプロジェクト作成 # vueプロジェクト内だとデフォがreactからvueに変わっている、賢い! amplify init # ユーザ認証を追加 amplify add auth # ネット上に公開用Webサーバを作成 amplify add hosting # ネット上のAWSに反映。AWSリソース作成に5分位かかる amplify push # 公開状態にして誰でもアクセス出来るようにする。 amplify publish # なんかエラーになったのでインストール yarn add core-js@latest2.6.2 # https://dev.適当なハッシュ値.amplifyapp.com/ がコマンドラインに表示されるのでブラウザで確認! # 不要になったらコマンド一発でamplifyプロジェクトをAWSから破棄! amplify delete |
3, vue.jsでフロントまわり(ログイン画面)を作る。
以下の5つのファイルをイジる。
main.js //amplifyパッケージを読み込む
src/route/index.js // urlのルーティング
src/store/index.js // ログインユーザ情報を保持
App.vue // ヘッダにログアウトボタン
views/Login.vue // ログイン画面(新規作成)
main.js //amplifyパッケージを読み込む
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' 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 // 文字列置換なのでデフォルトの英文が変更されたら、それに合わせて修正しないとダメ! let languageDict = { ja:{ 'Sign in to your account' : 'ログイン画面', 'Username' : 'ユーザ名', 'Enter your username' : 'ユーザ名を入力してください', 'Password' : 'パスワード', 'Enter your password' : 'パスワードを入力してください', 'Email' : 'メールアドレス', 'Forget your password? ' : 'パスワードを忘れた場合', 'Reset password' : 'パスワードのリセット', 'No account? ' : 'まだアカウントがない場合', 'Create account' : 'アカウント作成', 'Sign In' : 'サインイン', 'Create a new account' : 'ユーザ新規作成', 'Create Account' : 'ユーザ新規作成', 'Have an account?' : 'ユーザ作成済み?', } } AmplifyModules.I18n.putVocabularies(languageDict) new Vue({ router, store, render: h => h(App) }).$mount('#app') |
src/route/index.js // urlのルーティング
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
import Vue from 'vue' import Router from 'vue-router' import Home from '../views/Home.vue' import About from '../views/About.vue' import Login from '../views/Login.vue' import store from '../store/index.js' Vue.use(Router) // Amplify読み込み import { AmplifyEventBus } from 'aws-amplify-vue' import * 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: '/about', name: 'about', component: About, meta: { requiresAuth: true} }, { // トップページ 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/store/index.js // ログインユーザ情報を保持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { user: null }, mutations: { // ユーザー情報保存 setUser(state, user) { state.user = user }, }, actions: { }, modules: { } }) |
App.vue // ヘッダにログアウトボタン
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
<template> <div id="app"> <!-- 認証済みの時はメインの画面を表示 --> <div v-if="signedIn"> <div class="amplify-sign-out"> <!-- Amplify UIのSign Out用コンポーネントを追加 --> <amplify-sign-out/> <!-- ログイン済みユーザのusernameを表示 --> ようこそ、{{username}} さん </div> <div id="nav"> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> <router-view/> </div> <!-- 認証していない時はログイン画面を表示 --> <div v-else> <!-- ↓↓Amplify UIの認証コンポーネントで、電話番号は抜きにする↓↓ --> <amplify-authenticator v-bind:authConfig="authConfig"></amplify-authenticator> </div> </div> </template> <script> import { Auth } from 'aws-amplify' import { AmplifyEventBus } from 'aws-amplify-vue' window.LOG_LEVEL = 'VERBOSE'; export default { name: 'app', data(){ return { signedIn: false, username: '' } }, async beforeCreate() { // Auth.currentAuthenticatedUser()でユーザ情報を取得する。 // 取得できなければ認証ステータスをfalseに設定する try { let cognitoUser = await Auth.currentAuthenticatedUser() this.signedIn = true this.username = cognitoUser.username } catch (err) { this.signedIn = false } // 認証ステータスが変わった時に呼び出されるイベントを登録 AmplifyEventBus.$on('authState', async info => { if (info === 'signedIn') { let cognitoUser = await Auth.currentAuthenticatedUser() this.signedIn = true this.username = cognitoUser.username } else { this.signedIn = false } }); } }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } #nav { padding: 30px; } #nav a { font-weight: bold; color: #2c3e50; } #nav a.router-link-exact-active { color: #42b983; } </style> |
views/Login.vue // ログイン画面(新規作成)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<template> <div id="app"> <!-- ↓↓Amplify UIの認証コンポーネントで、電話番号は抜きにする↓↓ --> <amplify-authenticator v-bind:authConfig="authConfig"></amplify-authenticator> </div> </template> <script> export default { data(){ return{ // 新規登録時に、電話番号は無しにする authConfig: { signUpConfig: { defaultCountryCode: "44", hiddenDefaults: ['phone_number'] } } } } } </script> |
4, ローカルで修正して、公開Webサーバへ修正内容をpublishする
1 2 3 4 5 6 |
amplify publish # https://dev.適当なハッシュ値.amplifyapp.com/ がコマンドラインに表示されるのでブラウザで確認! # 不要になったらコマンド一発でamplifyプロジェクトをAWSから破棄! amplify delete |