developers

Build an Admin Dashboard with Express and Vue: Creating the Frontend

Learn how to use the Auth0 Management API to build an admin dashboard with Express and Vue

Starting from this chapter?

Setting up

Clone the application starter repo and check out the

creating-the-backend
branch:

git clone git@github.com:auth0-blog/express-vue-management-api.git --branch creating-the-backend

Install the dependencies for both the client and server:

cd server
npm install
cd ../client
npm install

Configure Auth0

Follow the Auth0 Configuration directions in the project README of the starter Vue and Express application.

Configure Management API

In the Auth0 dashboard, click on "APIs" in the left menu and then select "Auth0 Management API". From there, select "Machine to Machine Applications" and find the "Vue Express API" you just created. Click the switch next to it so that it says "Authorized".

Auth0 authorized API

Next, add permissions to the application. Click on the down arrow V next to the authorized switch. Select

read:users
,
delete:users
, and
read:user_idp_tokens
and then click "Update".

Create the

.env
file in the root of the
server
directory:

AUTH0_DOMAIN = your-domain.auth0.com
AUTH0_AUDIENCE = https://your-api-audience.com
CLIENT_ID = yourclientid
CLIENT_SECRET = yourclientsecret

To find your values, go to the Auth0 dashboard and click:

"APIs" > "Auth0 Management API" > "Test"

Select the Express API from the dropdown then click "Node.JS". You'll find the values for

CLIENT_ID
AND
CLIENT_SECRET
in the resulting code.

AUTH0_DOMAIN
and
AUTHO_AUDIENCE
can be found by clicking on "APIs" and then selecting the Vue Express API. Then click on "Quick Start" and select "Node.js". You'll see a value for audience, which you can paste directly into AUTH0AUDIENCE and then another value for issuer. Copy this and paste it into AUTH0DOMAIN, but leave off the
https://
and the trailing
/
at the end.

Test it

Start the Vue app:

cd client
npm run serve

Start the Express app:

cd server
npm start

Navigate to http://localhost:8000/users to see an array all of your users from the Express

/users
endpoint.

View the dashboard at: http://localhost:8080/dashboard

Creating the Dashboard with Vue

Here's what needs to be done on the Vue side:

  • Create a dashboard route
  • Create a new dashboard component
  • Create the user service to connect to the Express API
  • Make a
    GET
    request to the Express API's
    /users
    route
  • Loop over and display the users
  • Create a delete button and delete method
  • Add the delete method to the user service that makes a request to the Express API's
    /users/:id/delete
    route
  • Pass the user's access token along with their Express API requests
  • Restrict the route so that unauthenticated users will be kicked to the login screen

I'll go over each step here, but if you'd like a more in-depth explanation about making HTTP requests in Vue, I'd recommend going back and reading through the original article that this application is based on, Making HTTP Requests with Vue and Express.

If you haven't already, you can start the Vue application by navigating to the

client
directory in the terminal and running:

npm run serve

You can view it at http://localhost:8080

Add the Dashboard Route

First, go ahead and create the

/dashboard
route, which is where the user list will be displayed.

Open up

client/src/router/index.js
and paste the following in as the last element in the
routes
array:

{
    path: '/dashboard',
    name: 'dashboard',
    component: () => import('../views/Dashboard.vue')
}

Create the Dashboard Component

You'll notice that the

/dashboard
route is using the
Dashboard.vue
component. This doesn't exist yet, so go ahead and create it now.

Under

client/src/views
, create a new file called
Dashboard.vue
and paste in the following:

<template>
<div class="container">
  <h2 class="title is-size-3 has-text-centered">Welcome to your dashboard</h2>
  <div class="columns" v-if="message">
    <div class="column is-one-quarter is-offset-8">
      <div class="notification is-success">
        {{ message }}
      </div>
    </div>
  </div>
  <div class="columns is-multiline has-text-centered">
    <div v-for="user in users" :user="user" :key="user.id" class="column is-one-quarter">
      <img :src="user.picture" :alt="user.name" style="width:200px;margin-left:auto;margin-right:auto;"/>
      <h3 class="is-size-6">Name: {{ user.name }}</h3>
      <h3 class="is-size-6">Email: {{ user.email }}</h3>
      <h3 class="is-size-6">Last login: {{ user.last_login }}</h3>
      <h3 class="is-size-6">Login count: {{ user.logins_count }}</h3>
      <button @click="deleteUser(user.user_id)" class="button is-medium is-danger">Delete me 😵</button>
    </div>
  </div>
</div>
</template>
<script>
import UserService from '@/services/UserService.js';
export default {
    name: "Dashboard",
    data() {
    return {
      users: [],
      message: ''
    };
  },
  created() {
    this.getUserData(); // call getEventData() when the instance is created
  },
  methods: {
    async getUserData() {
      // Pass the access token to the getUsers service
      UserService.getUsers()
      .then(
        (users => {
          this.$set(this, "users", users);
        }).bind(this)
      );
    },
    async deleteUser(deleteId) {
      // Pass specified id to the deleteUser service
      UserService.deleteUser(deleteId)
      .then(
        (response => {
          this.message = response; 
          this.getUserData(); // get refreshed users
        })
      );
    }
  }
}
</script>
<style lang="scss" scoped>
  .notification {
    position: fixed;
    top: 800px;
    right: 40px;
  }
  .button {
    margin-top: 15px;
  }
</style>

In the script section, you're first importing the

UserService
. This is what your Vue application will use to connect to the Express API defined in the
server
directory. The Express API is responsible for getting the data from the Management API.

🧠 Your Vue client cannot reach out to the Management API directly because it would need an access token to do that, and as you saw earlier, that would require the client (Vue) to pass the client secret on the frontend, which isn't secure.

So, instead, the Express API handles the connection with the Management API. The Vue application then makes a request to the Express API using the

UserService
and receives the user information that the Express API passes back to it.

Of course, you wouldn't want just anybody to be able to access this user information. This is why the request to the Express API from the Vue client must be authorized. With the current implementation, anyone will be able to access the Express API endpoints to obtain the list of users and delete a user. Sit tight for now, and you'll be addressing that in an upcoming section.

The next important thing to note here are the 2 methods:

getUserData()
and
deleteUser(deleteId)
. The first method is called when the Dashboard instance is created. It's going to call the
getUsers()
method on the
UserService
and then set the result to the
users
array (defined under
data
). The next method will be called when the user clicks on a "Delete me" button underneath a user. It will send the selected user's
user_id
through to the
UserService.deleteUser()
method as a parameter.

If you glance back up now at the template section, you'll see where that

users
array comes into play. You're looping over it to display each individual user's avatar, name, email, last login date, and login count.

Finally, there's a

message
variable that will let us know that a user has been deleted.

Now, the

UserService
doesn't exist, so none of this is going to work yet. Go ahead and create it now.

Create the User Service

Create a new file called

UserService.js
under
client/src/services
and paste in the following:

import axios from "axios"
export default {
  async getUsers() {
    let res = await axios.get("http://localhost:8000/users");
    console.log(res.data);
    return res.data;
  },
  async deleteUser(id) {
    let res = await axios.get(`http://localhost:8000/users/${id}/delete`);
    return res.data;
  }
}

This allows the Vue application to make a

GET
request to the Express API using axios, a promise-based HTTP client.

You're calling the

/users
and
users/${id}/delete
routes that you built earlier in Express. The
/users
route is the one that returns the user information from the Management API.

So when the Vue application makes a

GET
request to the Express
/users
route, Express reaches out to the Management API and makes a request for the list of users. If the access token that the Express API presents is valid, then the Management API returns the users. Consequently, the Express API will then return that data to the requesting Vue application.

Again, it's important to verify that the Vue application is allowed to access this information. Whether or not it's allowed to access it is between the Express API and the Vue application, not the Management API. Currently, there's nothing in place to check that the Vue application is allowed to make this request to the Express API. You'll see how to implement this in the next section.

For now, make sure your Vue application and Express app are both still running in the terminal:

Vue application:

npm run serve

Express application:

npm start

Head to

http://localhost:8080/dashboard
, and you should now see your shiny new dashboard with all of your user's avatars and information displayed.

🚨 Resist the urge to click the "Delete" button on the accounts you want to keep! I recommend creating test user accounts through the Auth0 dashboard when you want to try out the delete button.

Vue Express Auth0 management API user dashboard

Next Step: I've created the Vue dashboardI ran into an issue