I built a login function with AWS Amplify, Amplify UI Vue, and Vue 3 ๐
In my previous article, I used Amplify UI Components "ui-vue" for Vue.js v2. This time, I tried building a login function with Vue 3's "ui-components."
Advance Preparation
- Build AWS Amplify and Vue 3 environment
AWS Amplify #002 - Building the environment
Overall composition
Backend - User Management
- Amazon Cognito
Frontend - Login function
- AWS Amplify
- Vue.js v3
Backend
First, let's build the backend.
AWS Amplify #003 - Add Authentication Function
If you only need authentication, you can implement it with these two commands!
amplify add auth
amplify push
This completes the building of the backend.
Frontend
Next, let's build the front-end.
execution environment
- node v16.10.0
- npm v7.24.0
First, install the two packages required for the project.
npm install aws-amplify
npm install @aws-amplify/ui-components
Finally, write the actual code for the login function.
Write the code for the authentication part in the router, and the UI can be displayed as it is by specifying an already existing component.
Overall composition
package.json
{
"name": "amplify-geo",
"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/ui-components": "^1.9.2",
"aws-amplify": "^4.3.4",
"core-js": "^3.6.5",
"vue": "^3.0.0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
/src
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import {
applyPolyfills,
defineCustomElements
} from '@aws-amplify/ui-components/loader';
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
applyPolyfills().then(() => {
defineCustomElements(window);
});
const app = createApp(App);
app.config.isCustomElement = tag => tag.startsWith('amplify-');
app.use(store).use(router).mount('#app');
/src/store
index.js
import { createStore } from 'vuex'
export default createStore({
state: {
user: null
},
mutations: {
setUser(state, user) {
state.user = user
},
},
getters: {
isSignIn: (state) => {
return state.user !== null
},
},
actions: {
},
modules: {
}
})
/src/router
index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Login from '../components/Login.vue'
import store from '../store/index.js'
import { Hub } from "@aws-amplify/core"
import Auth from "@aws-amplify/auth"
let user;
getUser().then((user) => {
if (user) {
router.push({path: '/'});
}
});
function getUser() {
return Auth.currentAuthenticatedUser().then((data) => {
if (data && data.signInUserSession) {
store.commit('setUser', data);
return data;
}
}).catch(() => {
store.commit('setUser', null);
return null;
});
}
Hub.listen("auth", async (data) => {
if (data.payload.event === 'signOut'){
user = null;
store.commit('setUser', null);
router.push({path: '/login'});
} else if (data.payload.event === 'signIn') {
user = await getUser();
router.push({path: '/'});
}
});
const routes = [
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/',
name: 'home',
component: Home,
meta: { requiresAuth: true}
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
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">
<img alt="Vue logo" src="../assets/logo.png">
<amplify-sign-out></amplify-sign-out>
</div>
</template>
<script>
export default {
name: 'Home',
components: {
}
}
</script>
/src/components
Login.vue
<template>
<div class="login">
<amplify-authenticator></amplify-authenticator>
</div>
</template>
<script>
export default {
name: 'login'
}
</script>
Let's check with a simple local server.
npm run serve
Startup a local server, register a user on the login screen and try logging in.
If you check the AWS console, you can see that the user has been successfully registered.
By using an AWS Amplify, Amplify UI Vue, and Vue 3, we could quickly build a login function ๐
I recommend Amplify because the introduction of the AWS Amplify CLI makes the serverless configuration much more convenient than before!
Top comments (5)
Hi, how do you generate the aws-exports file?
Hi, Generated by "amplify init".
day-journal.com/memo/aws-amplify-002/
Thanks man, it was generated the whole time but i just wasn't seeing it. Really informative piece. Thanks
Thanks for this - it's a good minimum working example for the auth process.
Now I'm interested in implementing TOTP MFA - do you have any tips?
Hi, You may find this link helpful!
docs.amplify.aws/lib/auth/mfa/q/pl...