Building a Login Function with AWS Amplify, Amplify UI Vue, and Vue 3
Tags: awsamplify, vue
Published: 2021-11-08 11:35:45

![img](https://day-journal.com/memo/images/try-067_00.png)  

<br>

### I built a login function with AWS Amplify, Amplify UI Vue, and Vue 3 :tada:  

In my previous [article](https://day-journal.com/memo/try-059), 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."

<br>

### Advance Preparation
- Build AWS Amplify and Vue 3 environment

[AWS Amplify #002 - Building the environment](https://day-journal.com/memo/aws-amplify-002)

<br>

### Overall composition

Backend - User Management
- Amazon Cognito

Frontend - Login function
- AWS Amplify
- Vue.js v3

<br>

## Backend

First, let's build the backend.  
[AWS Amplify #003 - Add Authentication Function](https://day-journal.com/memo/aws-amplify-003)

If you only need authentication, you can implement it with these two commands!

```shell
amplify add auth
```

```shell
amplify push
```

This completes the building of the backend.

<br>

## Frontend

Next, let's build the front-end.

### execution environment
- node v16.10.0
- npm v7.24.0

<br>

First, install the two packages required for the project.

```shell
npm install aws-amplify
```

```shell
npm install @aws-amplify/ui-components
```

<br>

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.

<br>

### Overall composition

![img](https://day-journal.com/memo/images/try-067_02.png)

<br>

### package.json

```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"
  ]
}
```

<br>

/src

### main.js

```javascript
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');
```

<br>

/src/store

### index.js

```javascript
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: {
  }
})
```

<br>

/src/router

### index.js

```javascript
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
```

<br>

/src/views

### Home.vue

```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>
```

<br>

/src/components

### Login.vue

```vue
<template>
    <div class="login">
        <amplify-authenticator></amplify-authenticator>
    </div>
</template>

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

<br>

Let's check with a simple local server.

```shell
npm run serve
```

<br>

Startup a local server, register a user on the login screen and try logging in.

![img](https://day-journal.com/memo/images/try-067_01.gif)  

<br>

If you check the AWS console, you can see that the user has been successfully registered.

![img](https://day-journal.com/memo/images/try-067_03.png)  

#### By using an AWS Amplify, Amplify UI Vue, and Vue 3, we could quickly build a login function :thumbsup: 

I recommend Amplify because the introduction of the AWS Amplify CLI makes the serverless configuration much more convenient than before!