Getting Started
Following the directions from Amplify Documentation
npm install -g @aws-amplify/cli
Create AWS Account. If you don’t already have an AWS account, you’ll need to create one in order to follow the steps outlined in this tutorial.
Configure Amplify if you havent done that before. There is a great video walkthrough or step by step instructions provided here
Workflow for Adding Authentication
Initialize the project for use with amplify. This project is the base Ionic Vue Application built from the cli using the blank template.
amplify init
Add authentication... just pick email and all the defaults with no additional details
amplify add auth
Once it is is done locally, push changes to the server
amplify push
Adding Authentication UI
For the authentication UI we are going to use the Amplify Authentication UI Component which you can find more information about here
Install the components, and aws-amplify
npm aws-amplify @aws-amplify/ui-components
There were some changes needed to get the components to work since they are custom components and also to get the code to compile since we are using javascript.
Addressing Javascript Issues
Add the following code to shims-vue.d.ts
// shims-vue.d.ts
declare module 'aws-exports'
Add the following code to tsconfig.json
// tsconfig.json
"allowJs": true,
Amplify Components UI Issues
Create a new file in the root of the project named vue.config.js
and add the following contents
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
options.compilerOptions = {
...(options.compilerOptions || {}),
isCustomElement: tag => tag.startsWith('amplify-')
};
return options;
});
}
};
Video
Adding Amplify Components To Application
This is covered in depth, in the video I have listed below the final source code changes in the project.
For the template, we have wrapped the whole page with the amplify-authenticator
component and set the username-alias
to email since that is what we specified in the setup of authentication. The contents of the page will only show when there is an authenticated user session
You can also see that we added a footer with the logout functionality. The footer contains the amplify-sign-out
component which displays a logout button.
<!-- script section of Home.vue -->
<template>
<!-- amplify-ui -->
<amplify-authenticator username-alias="email">
<ion-page>
<ion-header :translucent="true">
<ion-toolbar>
<ion-title>HOME</ion-title>
</ion-toolbar>
</ion-header>
<ion-content :fullscreen="true" class="ion-padding">
<p>LOGGED IN</p>
<p>{{ user?.attributes?.email }}</p>
</ion-content>
<ion-footer class="ion-padding">
<amplify-sign-out></amplify-sign-out>
</ion-footer>
</ion-page>
<!-- [end] amplify-ui -->
</amplify-authenticator>
</template>
For the script section, we listen for authentication events to see if we have an authenticated user in onMounted
. We save the unsubscribeAuth
value so we can cleanup when the component is unmounted
// script section of Home.vue
import {
IonContent,
IonPage,
IonTitle,
IonToolbar,
IonHeader,
IonFooter
} from "@ionic/vue";
import { defineComponent, onMounted, onUnmounted, ref } from "vue";
import { onAuthUIStateChange } from "@aws-amplify/ui-components";
export default defineComponent({
name: "Home",
setup() {
let unsubscribeAuth: any = null;
const curAuthState = ref<any>(null);
const user = ref<any>(null);
onMounted(() => {
unsubscribeAuth = onAuthUIStateChange((authState, authData) => {
curAuthState.value = authState;
user.value = authData;
});
});
onUnmounted(() => {
unsubscribeAuth();
});
return {
user,
};
},
components: {
IonContent,
IonPage,
IonTitle,
IonToolbar,
IonHeader,
IonFooter
},
});
// main.ts
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import { IonicVue } from "@ionic/vue";
/* Core CSS required for Ionic components to work properly */
import "@ionic/vue/css/core.css";
/* Basic CSS for apps built with Ionic */
import "@ionic/vue/css/normalize.css";
import "@ionic/vue/css/structure.css";
import "@ionic/vue/css/typography.css";
/* Optional CSS utils that can be commented out */
import "@ionic/vue/css/padding.css";
import "@ionic/vue/css/float-elements.css";
import "@ionic/vue/css/text-alignment.css";
import "@ionic/vue/css/text-transformation.css";
import "@ionic/vue/css/flex-utils.css";
import "@ionic/vue/css/display.css";
/* Theme variables */
import "./theme/variables.css";
/* AMPLIFY */
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)
.use(IonicVue)
.use(router);
app.config.isCustomElement = (tag) => tag.startsWith("amplify-");
router.isReady().then(() => {
app.mount("#app");
});
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
options.compilerOptions = {
...(options.compilerOptions || {}),
isCustomElement: tag => tag.startsWith('amplify-')
};
return options;
});
}
};