How to quickly authenticate a dashboard in Vue.js using Appwrite and Auth0
Tags: vue, appwrite, auth0, javascript
Published: 2022-06-30 14:47:04

In the age of large multi-user websites, it is essential to control what information a user has access to. This is achieved with authentication, a process which collects and identifies users who request access to an application or database.

## What we are building

This article discusses authenticating, collecting, and displaying a piece of user information with Appwrite’s auth0 provider.

**GitHub URL**

https://github.com/Iheanacho-ai/auth0-authentication

## Prerequisites 

To get the most out of this project, the following are required:

- A basic understanding of CSS, JavaScript, and Vue.js.
- Docker Desktop installed on the computer; run the `docker -v` command to verify that we have Docker Desktop installed. If not, install it from the [Get Docker documentation](https://docs.docker.com/get-docker/).
- An Appwrite instance running on our computer. Check out [this article](https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&utm_medium=hackmamba) to create a local Appwrite instance; we will use Appwrite’s robust database and Realtime service to manage our application.
- An auth0 account; [create a free account](https://auth0.com/signup) if you don’t have one.


## Setting up our Vue.js application

We install the [Vue CLI](https://cli.vuejs.org/) by running these terminal commands to create a new Vue project.

```bash
    npm install -g @vue/cli
    # OR
    yarn global add @vue/cli
```
After installing the Vue CLI, we navigate to our preferred directory and create a new project.

```bash
    vue create <name of our project>
```
We change the directory to the project and start a development server with:

```bash
    npm run serve
```
To see the app, we go to http://localhost:8080/


## Installing dependencies

**Installing Tailwind CSS**

[Tailwind CSS](https://tailwindcss.com/) is a "utility-first" CSS framework that allows us to create user interfaces for web applications rapidly.

To install Tailwind CSS in our project, we run the following terminal commands.

```bash
    npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
    npx tailwindcss init -p
```
These commands create two files in the root directory of our project, `tailwind.config.js` and `postcss.config.js`.

In our `tailwind.config.js`, we add the paths to all our template files with this code below.

```js
    module.exports = {
      purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
      content: [],
      theme: {
        extend: {},
      },
      plugins: [],
    }
```
Next, we add the tailwind directives in our `src/index.css` file.

```css
    @tailwind base;
    @tailwind components;
    @tailwind utilities;
```
**Installing Vue router**

Routing is the technology used to switch between different pages in our application based on the changes in the current URL.

We run this terminal command to enable our application to use [Vue Router](https://router.vuejs.org/).

```js
    npm install vue-router@4
    
    #or 
    
    yarn add vue-router@4   
```
**Installing Appwrite**

[Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog) is an open-source, end-to-end, backend server solution that allows developers to build applications faster. 

To use Appwrite in our Vue application, we install the Appwrite client-side SDK for web applications.

```bash
    npm install appwrite
```

## Creating a new Appwrite project

During the creation of the Appwrite instance, we specified what hostname and port we see in our console. The default value is [localhost:80](http://localhost/), so go to [localhost:80](http://localhost/) and create a new account to see our console.

From our console, click the **Create Project** button to start a new project.

![Appwrite Console](https://paper-attachments.dropbox.com/s_314B50E78D2533608F0DEE9BE97FEF3C5B7916B2F8CAC55559F4DCA3A07D86F6_1648400276700_Screenshot+64.png)


Our project dashboard appears once we have created the project. At the top of the page, there is a **Settings** bar. Click it to access the **Project ID** and **API Endpoint**.  


![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653478724464_Screenshot+339.png)


We copy the **Project ID** and **API Endpoint**, which we need to initialize the Appwrite Web SDK.

![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653478756414_Screenshot+340.png)


We create an `init.js` file at our project's root directory to initialize the Appwrite Web SDK with the following code.

```js
    import { Appwrite } from 'appwrite';
    export const sdk = new Appwrite();
    sdk
      .setEndpoint('http://localhost/v1') // Replace this with your endpoint
      .setProject('projectID'); // Replace this with your ProjectID
    
```

**Enabling the auth0 provider in our application**

In the Appwrite web [Console](http://localhost/console), we click on **Users** on the left side of the dashboard to set up the auth0 provider for our application.


![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653478855179_Screenshot+341.png)


We go to the **Settings** tab to see the OAuth2 providers supported by Appwrite.

![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653479038602_Screenshot+341.png)



![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653479106333_Screenshot+342.png)


**Creating an application on the auth0 dashboard**

To enable us to use Appwrite’s auth0 provider, we create an application on the auth0 dashboard. Check out the [auth0 documentation](https://auth0.com/docs/get-started/auth0-overview/create-applications) to understand how to create an auth0 application.

After creating our auth0 application, we click on the **Settings** tab to copy the **Domain**, **Client ID**, and **Client Secret** information of our auth0 application. We will use this information in our Appwrite console.


![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653481417319_Screenshot+349.png)


In our Appwrite console, we toggle the auth0 provider to open up the **Auth0 OAuth2 settings.**


![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653499528815_Screenshot+342.png)




![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653481019829_Screenshot+348.png)


Fill out the input fields with the information gathered from the auth0 dashboard. 

Next, we copy the redirect URL on the Appwrite console and paste it into the **Allowed Callback URLs** input field on our auth0 dashboard.


![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653482406412_Screenshot+352.png)



## Authenticating users in our application

Our application will contain two pages. The first page will authenticate and log in a user using the Appwrite auth0 provider, and the second page will display the user details.

**Creating our login page**

Our login page will consist of a button to allow users to log in via auth0.

We create a `views` folder for this user interface in our' src' folder. This `src/views` folder will contain a `Home.vue` file.

With this code, we create our login page in our `src/views/Home.vue` file.

```vue
    <template>
      <div class="login">
          <p>Click on this button to login</p>
          <button class= "button">Login with autho</button>
        </div>
    </template>
```
## Routing to our pages 

In our `src/main.js` file, we enable our application to use `router` to navigate to different pages with this piece of code.

```js
    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import './index.css';
     
    createApp(App).use(router).mount('#app')
```
Next, we create a `router` folder in our `src` folder. Our `router` folder will contain an `index.js` file. This file will be responsible for defining what routes lead to specific components.

```js
    // src/router/index.js
    import { createRouter,createWebHistory } from 'vue-router'
    import Home from '@/views/Home'
    import Notification from '@/views/Notifications'
    const routes = [
        {
            path: '/',
            name: 'Home',
            component: Home
        }
    ]
    const router = createRouter({
        history: createWebHistory(process.env.BASE_URL),
        routes
    })
    export default router;
```
The code block above does the following:

- Creates a `routes` array containing the route's path and the component we want the route to lead to.
- Facilitates routing using the Vue `createRouter` method, which receives an object as a parameter. This object parameter has two fields, a history field and a route field, whose value is our route array.

Next, in our `App.vue` file, we add the `router-view` component and the CSS styles for the login page.

```vue
    <template>
      <div class="app-container">
        <router-view ></router-view>
       </div>
    </template>

    <script>
      export default {
        name: 'App',
      }
    </script>

    <style>
      .login{
        width: 450px;
        height: 150px;
        background: #fff;
        box-shadow: 0 10px 30px rgba(0,0,0,0.1);
        border-radius: 7px;
        margin: 10% auto;
        text-align: center;
        padding: 30px;
      }

      .button{
        width: 150px;
        height: 40px;
        background-color: #111;
        color: #fff;
        border-radius: 30px;
      }
    </style>
    
```
The router-view component represents our component. In the code block above, we specify the position at which our app is situated.

To avoid errors resulting from non-multi-level component names, we replace our `vue.config.js` file with this code.

```js
    const { defineConfig } = require('@vue/cli-service')
    module.exports = defineConfig({
      transpileDependencies: true,
      lintOnSave:false
    })
```
Go to [http://localhost:8080/](http://localhost:8080/) to see our Home page.


![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653384855153_Screenshot+336.png)



**Creating the user profile page**

In our `src/views` folder, we create a `Dashboard.vue` file to display the logged-in user profile.

```vue
    <template>
        <div class="user-details">
            <p><span>Name: </span></p>
            <p><span>Email: </span></p>
            <button class= "button">LogOut with Auth0</button>
        </div>
    </template>
```
Next, we add the CSS styles for the user profile in the `App.vue` file.

```css
    <style>
    .login, .user-details{
      width: 450px;
      height: 150px;
      background: #fff;
      box-shadow: 0 10px 30px rgba(0,0,0,0.1);
      border-radius: 7px;
      margin: 10% auto;
      text-align: center;
      padding: 30px;
    }

    .button{
      width: 150px;
      height: 40px;
      background-color: #111;
      color: #fff;
      border-radius: 30px;
    }

    span{
      font-weight: 600;
      
    }
    </style>
```
We add a route to the `routes` object in the `src/router/index.js` file to view our **Dashboard** page in the browser.

```js
   // src/router/index.js
   const routes = [
        {
            path: '/',
            name: 'Home',
            component: Home
        },
       {
            path: '/dashboard',
            name: 'Dashboard',
            component: Dashboard
        }
    ]
```

Here is how our `src/router/index.js` file looks.

```js
    import { createRouter,createWebHistory } from 'vue-router'
    import Home from '@/views/Home'
    import Dashboard from '@/views/Dashboard'
    const routes = [
        {
            path: '/',
            name: 'Home',
            component: Home
        },
        {
            path: '/dashboard',
            name: 'Dashboard',
            component: Dashboard
        }
    ]
    const router = createRouter({
        history: createWebHistory(process.env.BASE_URL),
        routes
    })
    export default router;
```

To see our user profile page, go to http://localhost:8080/dashboard.


![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653384988659_Screenshot+337.png)



**Authenticating a user with Appwrite’s auth0 provider**

To allow a user to log in to their account using the auth0 provider, we write this piece of code in the `Home.vue` file of our project.

```vue
    <script>
    import {sdk} from '../../init';
      export default {
        name: 'Home',
        methods: {
          loginWithAutho: async function(){
            try {
              await sdk.account.createOAuth2Session('auth0', 'http://localhost:8080/dashboard', 'http://localhost:8080/error')
            } catch (error) {
              console.log(error)
            }
          }
        }
      };
    </script>
```
We create an account session using the Appwrite `createOAuth2Session` method in the code block above. This `createOAuth2Session` method receives three parameters:

- The OAuth2 provider we want to sign in a user with, which, in this example, is auth0.
- The success argument is a redirect URL back to our app when the login is complete.
- The failure argument is a redirect URL when the login fails.

 
Next, we pass the `loginWithAutho` method on the `@click` event listener on the **Login with autho** button.

```vue
    <button class= "button" @click="loginWithAutho">Login with autho</button>
```
Here is how the `Home.vue` file looks.

```vue
    <template>
        <div class="login">
            <p>Click on this button to login</p>
            <button class= "button" @click="loginWithAutho">Login with autho</button>
          </div>
    </template>
    
    <script>
    import {sdk} from '../../init';
      export default {
        name: 'Home',
        methods: {
          loginWithAutho: async function(){
            try {
              await sdk.account.createOAuth2Session('auth0', 'http://localhost:8081/dashboard', 'http://localhost:8081/error')
            } catch (error) {
              console.log(error)
            }
          }
        }
      };
    </script>
```
**Displaying the stored user in our application**

To display the user currently logged into our application, we write this code in the `script` section of our  `Dashboard.vue` file.

```vue
    <script>
    import {sdk} from '../../init';
      export default {
        name: 'Dashboard',
        data(){
          return{
            namme: '',
            email: '',
            response: ''
          }
        },
        mounted: function(){
            this.getUserSession()
        },
        methods: {
          getUserSession: async function(){
            try {
              this.response = await sdk.account.get()
              if (this.response) {
                this.name = this.response.name,
                this.email = this.response.email 
              }
              
            } catch (error) {
              console.log(error)
            }
          },
          logOutWithAutho: async function(){
            try {
              await sdk.account.deleteSession('current')
              alert('logout successful')
              this.$router.push('/') 
            } catch (error) {
              console.log(error)
            }
          }
        }
      };
    
    </script>
```
In the code block above, we do the following:

- Create `name`, `email`, and `response` variables to hold a user's information.
- Create a `getUserSession` function to fetch the current logged in user information. This `getUserSession` function updates the `name`, `email`, and `response` variable.
- Use the mounted lifecycle hook to run the `getUserSession` function when the application mounts.
- Create a `logOutWithAutho` function that logs a user out of our application by using the Appwrite `deleteSession` method. This `logOutWithAutho` function then navigates to our application’s home page.
- Logs any error encountered during user logout.

In the `Dashboard.vue` file, we render the `name` and `email` variables. Next, we pass the `logOutWithAutho` function to the `@click` event listener on the **LogOut with Auth0** button.

```vue
    <template>
      <div class="user-details">
        <p><span>Name: </span>{{name}}</p>
        <p><span>Email: </span>{{email}}</p>
        <button class= "button" @click="logOutWithAutho">LogOut with Auth0</button>
      </div>
    </template>
```

Here is how our application looks.

![Appwrite Console](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653500888763_auth0.gif)

## Conclusion

This article discussed using Appwrite's OAuth2 auth0 provider to authenticate a user. 

## Resources

Here are some resources that might be helpful.

- [Create a local Appwrite instance in 3 steps](https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&utm_medium=hackmamba)
- [Create auth0 applications](https://auth0.com/docs/get-started/auth0-overview/create-applications)
- [Account API](https://appwrite.io/docs/client/account?sdk=web-default#accountCreateOAuth2Session?utm_source=hackmamba&utm_medium=blog&utm_campaign=auth0_auth0-authentication-vue)