developers

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

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

Nov 16, 2020 ā€¢ 8 min read

Starting from this chapter?

Clone the application starter repo:

git clone git@github.com:auth0-blog/vue-express-auth.git

Follow the directions in the project README.

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".

Calling the Management API with Express

The Express API is now registered in the dashboard, and the Auth0 Management API is set up and ready to issue an access token to the Express API. So what's next? Now, you have to do the client credentials dance to get an access token.

Client Credentials Flow

The OAuth 2.0 RFC 6794 defines how trusted clients (your Express API) can use the client credentials to request an access token from a resource owner (the Auth0 Management API):

ā— The client can request an access token using only its client credentials (or other supported means of authentication) when the client is requesting access to the protected resources under its control, or those of another resource owner that have been previously arranged with the authorization server (the method of which is beyond the scope of this specification).

Because the Management API access token is requested on behalf of the Express application, not a user, it doesn't make sense to ask for a username and password to verify who the requester is. Instead, you can use the Express application's client credentials (

client_id
and
client_secret
) to authenticate the application.

Machine to machine client credentials grant > This diagram depicts the client credentials grant flow described below

  • The Express application authenticates with the Auth0 Authorization Server using its
    client_id
    and
    client_secret
  • The Auth0 Authorization Server validates the
    client_id
    and
    client_secret
  • The Auth0 Authorization Server issues an access token and passes it back to your application
  • The Express application passes this token when it makes a request to the Management API
  • The Management API responds with the requested data

Requesting an Access Token

The Express application needs to request an access token for the Management API from the Auth0 server. There are three ways to do this.

1) Make a

POST
request to the token endpoint using your Express API client ID and client secret, as shown below:

let request = require("request");

let options = {
    method: 'POST',
    url: 'https://YOUR-DOMAIN.auth0.com/oauth/token',
    headers: { 'content-type': 'application/json' },
    body: '{
        "client_id": "yourclientid",
        "client_secret": "yourclientsecret",
        "audience": "https://YOUR-DOMAIN.auth0.com/api/v2",
        "grant_type": "client_credentials"
    }'
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);
});

This will return the access token (with a 24-hour expiration) and token type:

{
  "access_token": "somelongstring",
  "token_type": "Bearer"
}

2) Use the Auth0 Node Authentication API Client

let AuthenticationClient = require('auth0').AuthenticationClient;
 
let auth0 = new AuthenticationClient({
  domain: '{YOUR_ACCOUNT}.auth0.com',
  clientId: '{CLIENT_ID}',
  clientSecret: '{CLIENT_SECRET}'
});
 
auth0.clientCredentialsGrant(
  {
    audience: 'https://{YOUR_ACCOUNT}.auth0.com/api/v2/',
    scope: '{MANAGEMENT_API_SCOPES}'
  },
  function(err, response) {
    if (err) {
      // Handle error.
    }
    console.log(response.access_token);
  }
);

This performs a Client Credentials Grant using the

clientId
and
clientSecret
of the client that was registered in the Auth0 dashboard, in this case, the Express API. This will return the access token, scopes, expiration, and token type. You'll then send this access token along with every request you make to the Management API.

3) Use the Auth0 Node Management API Client

let ManagementClient = require('auth0').ManagementClient;

let auth0 = new ManagementClient({
  domain: '{YOUR_ACCOUNT}.auth0.com',
  clientId: '{YOUR_CLIENT_ID}',
  clientSecret: '{YOUR_CLIENT_SECRET}',
  scope: 'read:users delete:users'
});

Finally, there also exists an option to automatically receive an access token in the background using the Auth0 Node Management API Client. This is similar to option 2. The Client Credentials Grant still takes place behind the scenes and will retrieve a Management API access token along with its expiration. It then automatically caches this access token for the time specified in the expiration.

For this tutorial, you'll be using the third option. This option allows you to use the Management Client to easily make requests to the Management API.

Getting your Access Token in Express

Now that you know how the client credentials flow works and how you're going to implement it in your application, it's finally time to write some code!

Head back to your code editor and open

server/server.js
from the Vue Express application you cloned earlier.

šŸ“ Here's an overview of what you're going to do:

  • Install and import the Auth0
    ManagementClient
  • Create a
    .env
    file for your confidential values
  • Add
    clientId
    and
    clientSecret
    to your
    authConfig
    object
  • Create a new instance of the
    ManagementClient
    with your
    domain
    ,
    clientId
    , and
    clientSecret

Make sure you're in the

server
directory in your terminal and install the
node-auth0
package by running:

npm install auth0

Find the

require
functions at the top of your
server/server.js
file and add the following line to import
ManagementClient
.

// ...
// import statements
const ManagementClient = require('auth0').ManagementClient;
// app.use

Next, toward the top of the file, you should see an

authConfig
object directly underneath the
require
and
use
methods. This needs to be modified to include your client secret and client ID from the Express API.

Because these are sensitive values, you should not save them directly in the code. If you ever share this code or upload it to GitHub, you risk leaking your client secret. Instead, it's best to create a

.env
file and add this file to your
.gitignore
. To do this, navigate to the
server
directory and run the following command in your terminal:

npm install dotenv

At the top of your

server/server.js
file add this line:

require('dotenv').config();

Now create a file in the root of the

server
directory called
.env
and add the following to it:

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

The values for

CLIENT_ID
and
CLIENT_SECRET
can be found back in the Auth0 dashboard on the Auth0 Management API page that you set up earlier.

If you already closed this tab, just click on "APIs" > "Auth0 Management API" > "Test" and then select the Express API from the dropdown. Next, click on "Node.JS", and you can copy the

client_id
and
client_secret
from the resulting code below.

If you followed the setup instructions from the README, you should already have an object in

server.js
called
authConfig
that contains the audience and domain values. Grab those and paste them into their corresponding spots in
.env
.

If you don't have the domain and audience values, they can be found by clicking on "APIs" in the left-hand menu and then selecting the Vue Express API. Next, click on "Quick Start" and then select "Node.js". You'll see a value for

audience
, which you can paste directly into
AUTH0_AUDIENCE
and then another value for
issuer
. Copy this and paste it into
AUTH0_DOMAIN
.

āš ļø Important: For

AUTH0_DOMAIN
, omit the
https://
and the trailing
/
. It should be formatted exactly as shown above.

Next, modify the

authConfig
object in
server/server.js
to use those environment variables as follows:

// Set up Auth0 configuration
const authConfig = {
  domain: process.env.AUTH0_DOMAIN,
  audience: process.env.AUTH0_AUDIENCE,
  clientId: process.env.CLIENT_ID,
  clientSecret: process.env.CLIENT_SECRET
};

And finally, you'll create a new instance of the

ManagementClient
, which takes an object that contains your Auth0 domain, client ID, and client secret.

Paste this just below the

authConfig
object in
server/server.js
:

const managementAPI = new ManagementClient({
  domain: authConfig.domain,
  clientId: authConfig.clientId,
  clientSecret: authConfig.clientSecret
});

Now, when you use

managementAPI
, it will automatically perform the Client Credentials Grant in the background using the domain, client ID, and the client secret, which will result in an access token that can be used to make requests to the Management API.

Now it's time to test it out.

Calling the Management API

Back in

server/server.js
, scroll down to where the
events
array is defined. Paste in the following code right below it:

app.get('/users', (req, res) => {
  managementAPI
    .getUsers()
    .then(function(users) {
      res.send(users);
    })
    .catch(function(err) {
      console.log(err);
    });
});

This will create an API route in your Express application that calls the Management API Node Client to get all users whenever that route is accessed.

To verify that it's working, switch to your terminal and start your Express application if you haven't already by running:

npm start

Navigate to

http://localhost:8000/users
in your browser, and you should see all of the users that have signed up for your application! šŸ’ƒ

If you're getting an error, reach out in the comments below, and I'll try to help troubleshoot.

You're also going to need a route to delete a user, so since you're here, just set that up now. Below the previous route, paste in:

app.get('/users/:id/delete', (req, res) => {
  managementAPI
  .deleteUser({ id: req.params.id })
  .then(response => {
    res.send('User deleted!');
  })
  .catch(function(err) {
    res.send(err);
  });
});

This will grab the

id
of the user, which will be passed to the server from the Vue client. Then it will call the Management API to do the deletion.

Now that you're able to pull all of your users into the application and delete a user, it's time to switch to the frontend.

Next Step: I've set up the Express backendI ran into an issue