Vue: Calling an API

View on Github

Vue: Calling an API

Gravatar for steve.hobbs@auth0.com
By Steve Hobbs

This tutorial demonstrates how to make calls to an external API We recommend that you log in to follow this quickstart with examples configured for your account.

I want to explore a sample app

2 minutes

Get a sample configured with your account settings or check it out on Github.

View on Github
System requirements: Vue 2.6.11 | Vue CLI 4.2.2

Most single-page apps use resources from data APIs. You may want to restrict these resources so only authenticated users with sufficient privileges can access them. Auth0 lets you manage access to these resources using API Authorization.

In this tutorial, you'll create a simple API using Express to validate incoming JWT-formatter access tokens. You will then see how to call this API using an access token granted by the Auth0 authorization server.

Create an API

In the APIs section of the Auth0 dashboard, click Create API. Provide a name and an identifier for your API. You will use the identifier later when you're configuring your Javascript Auth0 application instance. For Signing Algorithm, select RS256.

Create API

Create the Backend API

For this example, you'll create an Express server that acts as the backend API. This API will expose an endpoint to validate incoming JWT-formatted access tokens before returning a response.

Start by installing the following packages:

npm install express express-oauth2-jwt-bearer npm-run-all

Was this helpful?

/

Next, create a new file server.js with the following code:

const express = require("express");
const { auth } = require("express-oauth2-jwt-bearer");

// Create a new Express app
const app = express();

// Define middleware that validates incoming bearer access token JWTs
const checkJwt = auth({
  issuerBaseURL: "https://YOUR_DOMAIN",
  audience: "YOUR_API_IDENTIFIER"
});

// Define an endpoint that must be called with an access token
app.get("/api/external", checkJwt, (req, res) => {
  res.send({
    msg: "Your Access Token was successfully validated!"
  });
});

// Start the app
app.listen(3001, () => console.log('API listening on 3001'));

Was this helpful?

/

The above API has one available endpoint, /api/external, that returns a JSON response to the caller. This endpoint uses the checkJwt middleware to validate the supplied bearer token. If the token is valid, the request is allowed to continue. Otherwise, the server returns a 401 Unauthorized response.

Finally, modify package.json to add two new scripts dev and api that can be used to start the frontend and the backend API together:

{
  "name": "02-calling-an-api",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "dev": "npm-run-all --parallel serve api",
    "api": "node server.js"
  },

  // .. package dependencies and other JSON nodes
}

Was this helpful?

/

You can now start the project using npm run dev in the terminal, and the frontend Vue.js application will start up alongside the backend API.

Set up a proxy to the backend API

To call the API from the frontend application, the development server must be configured to proxy requests through to the backend API. To do this, add a vue.config.js file to the root of the project and populate it with the following code:

module.exports = {
  devServer: {
    proxy: {
      "/api": {
        target: "http://localhost:3001"
      }
    }
  }
};

Was this helpful?

/

With this in place, the frontend application can make a request to /api/external and it will be correctly proxied through to the backend API at http://localhost:3001/api/external.

Restart the application

If you are already running the application using npm run serve, then stop that process for now. Restart the app using the following command, which will run both the frontend app and the backend API together:

PORT=3000 npm run dev

Was this helpful?

/

Add the Audience

The API backend you created above expects API calls to have a JSON Web Token for authorization. To do this, you must instruct Auth0 to issue an access token in JWT format. This is done by supplying the API identifier in an audience parameter when users authenticate, telling Auth0 which API you want an access token for.

Open auth_config.json in the root of the project and make sure that a value for audience is exported along with the other settings. The value for audience should be the "API identifier" for the API you created above:

{
  "domain": "YOUR_DOMAIN",
  "clientId": "YOUR_CLIENT_ID",
  "audience": "YOUR_API_IDENTIFIER"
}

Was this helpful?

/

Finally, open main.js and configure the Auth0 plugin with this audience value:


// .. other imports

// NEW - import the audience
import { domain, clientId, audience } from "../auth_config.json";

// ..

Vue.use(Auth0Plugin, {
  domain,
  clientId,
  audience,   // NEW - configure the plugin with the audience value
  onRedirectCallback: appState => {
    router.push(
      appState && appState.targetUrl
        ? appState.targetUrl
        : window.location.pathname
    );
  }
});

// .. more Vue configuration ..

Was this helpful?

/

Call the API Using an Access Token

Modify the frontend Vue.js application to include a page that calls the API using an access token. Like the previous tutorial, you'll need to change the Vue router and add a new view with a button that calls the API.

Install the Axios package

Install the axios HTTP library, which will allow us to make HTTP calls out to the backend API:

npm install axios

Was this helpful?

/

Add a new page

Next, create a new file ExternalApi.vue inside the views folder. Add a button to call the API and an HTML element that can display the result of the API call.

Use the getTokenSilently method of the Auth0 wrapper to get an access token, and then use Axios to make the API call. Attach the access token to the call by setting it as the value for the Authorization header, as in the following example:

<template>
  <div>
    <button @click="callApi">Call</button>
    <p>{{ apiMessage }}</p>
  </div>
</template>

<script>
import axios from "axios";

export default {
  name: "external-api",
  data() {
    return {
      apiMessage: ""
    };
  },
  methods: {
    async callApi() {
      // Get the access token from the auth wrapper
      const token = await this.$auth.getTokenSilently();

      // Use Axios to make a call to the API
      const { data } = await axios.get("/api/external", {
        headers: {
          Authorization: `Bearer ${token}`    // send the access token through the 'Authorization' header
        }
      });

      this.apiMessage = data;
    }
  }
};
</script>

Was this helpful?

/

Modify the Vue router to include a route to this new page whenever the /external-api URL is accessed:

// src/router/index.js

// .. other imports

// NEW - import the view for calling the API
import ExternalApiView from "../views/ExternalApi.vue";

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    // ... other routes,

    // NEW - add a new route for the new page
    {
      path: "/external-api",
      name: "external-api",
      component: ExternalApiView,
      beforeEnter: authGuard
    }
  ]
});

Was this helpful?

/

Note that this new route also uses authGuard from the previous tutorial, which prevents access to the page unless the user is authenticated.

Finally, modify the navigation bar to include a link to the new page:

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link>|
      <router-link to="/about">About</router-link>|

      <!-- NEW - add a link to the new page -->
      <router-link to="/external-api">External Api</router-link>

      <!-- .. other HTML elements -->

    </div>
    <router-view />
  </div>
</template>

Was this helpful?

/

Checkpoint

Now you will be able to run the application, browse to the "External API" page and press the "Call" button. The application will make a call to the external API endpoint and produce a message on the screen that says "Your Access Token was successfully validated!".

Use Auth0 for FREE