Skip to content

Commit 30a1099

Browse files
author
Steve Hobbs
committed
Inlined the 'create the backend API' include
1 parent 761b2ea commit 30a1099

File tree

1 file changed

+35
-59
lines changed

1 file changed

+35
-59
lines changed

03-Calling-an-API/README.md

Lines changed: 35 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -68,41 +68,39 @@ For **Signing Algorithm**, select **RS256**.
6868

6969
![Create API](../docs/create-api.png)
7070

71-
### Modify the Backend API
71+
### Create the Backend API
7272

73-
For this tutorial, let's modify the API to include a new endpoint that expects an Access Token to be supplied.
73+
For this example, you'll create an [Express](https://expressjs.com/) server that acts as the backend API. This API will expose an endpoint to validate incoming ID Tokens before returning a response.
7474

75-
> **Note** In a real scenario, this work would be done by the external API that is to be called from the frontend. This new endpoint is simply a convenience to serve as a learning exercise.
75+
Start by installing the following packages:
7676

77-
Open `server.js` and add a new Express route to serve as the API endpoint, right underneath the existing one:
78-
79-
```js
80-
// server.js
81-
82-
// ... other code
77+
```bash
78+
npm install express express-jwt jwks-rsa npm-run-all
79+
```
8380

84-
// This is the existing endpoint for sample 2
85-
app.get("/api/private", checkJwt, (req, res) => {
86-
res.send({
87-
msg: "Your ID Token was successfully validated!"
88-
});
89-
});
81+
- [`express`](https://github.com/expressjs/express) - a lightweight web server for Node
82+
- [`express-jwt`](https://www.npmjs.com/package/express-jwt) - middleware to validate JsonWebTokens
83+
- [`jwks-rsa`](https://www.npmjs.com/package/jwks-rsa) - retrieves RSA signing keys from a JWKS endpoint
84+
- [`npm-run-all`](https://www.npmjs.com/package/npm-run-all) - a helper to run the SPA and backend API concurrently
9085

91-
// Add the new endpoint here:
92-
app.get("/api/external", checkJwt, (req, res) => {
93-
res.send({
94-
msg: "Your Access Token was successfully validated!"
95-
});
96-
});
97-
```
86+
Next, create a new file `server.js` with the following code:
9887

99-
Notice that it continues to use the same `checkJwt` middleware in order to validate the Access Token. The difference here is that the Access Token must be validated using the API identifier, rather than the client ID that we used for the ID Token.
88+
```js
89+
const express = require("express");
90+
const jwt = require("express-jwt");
91+
const jwksRsa = require("jwks-rsa");
10092

101-
> **Note** The API identifier is the identifer that was specified when the API was created in the [Auth0 dashboard](https://manage.auth0.com/#/apis).
93+
// Create a new Express app
94+
const app = express();
10295

103-
Therefore, modify the `checkJwt` function to include the API identifier value in the `audience` setting:
96+
// Set up Auth0 configuration
97+
const authConfig = {
98+
domain: "<YOUR AUTH0 DOMAIN>",
99+
audience: "<YOUR AUTH0 API IDENTIFIER>"
100+
};
104101

105-
```js
102+
// Define middleware that validates incoming bearer tokens
103+
// using JWKS
106104
const checkJwt = jwt({
107105
secret: jwksRsa.expressJwtSecret({
108106
cache: true,
@@ -111,45 +109,23 @@ const checkJwt = jwt({
111109
jwksUri: `https://${authConfig.domain}/.well-known/jwks.json`
112110
}),
113111

114-
// Modify the audience to include both the client ID and the audience from configuration in an array
115-
audience: [authConfig.clientID, authConfig.audience],
116-
issuer: `https://${authConfig.domain}/`,
112+
audience: authConfig.audience,
113+
issuer: `https://${authConfig.domain}"/`,
117114
algorithm: ["RS256"]
118115
});
119-
```
120-
121-
> **Note** As the `audience` property accepts an array of values, both the client ID and the API identifier can be given, allowing both the ID Token and the Access Token to be verified using the same middleware.
122-
123-
Finally, modify the `authConfig` object to include your `audience` value:
124-
125-
```js
126-
const authConfig = {
127-
domain: "<YOUR AUTH0 DOMAIN>",
128-
clientID: "<YOUR AUTH0 CLIENT ID>",
129-
audience: "<YOUR AUTH0 API IDENTIFIER>"
130-
};
131-
```
132116

133-
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:
134-
135-
```json
136-
{
137-
"name": "03-calling-an-api",
138-
"version": "0.1.0",
139-
"private": true,
140-
"scripts": {
141-
"serve": "vue-cli-service serve",
142-
"build": "vue-cli-service build",
143-
"lint": "vue-cli-service lint",
144-
"dev": "npm-run-all --parallel serve api",
145-
"api": "node server.js"
146-
}
117+
// Define an endpoint that must be called with an access token
118+
app.get("/api/external", checkJwt, (req, res) => {
119+
res.send({
120+
msg: "Your Access Token was successfully validated!"
121+
});
122+
});
147123

148-
// .. package dependencies and other JSON nodes
149-
}
124+
// Start the app
125+
app.listen(3001, () => console.log("API listening on 3001"));
150126
```
151127

152-
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.
128+
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 using your tenant's [JSON Web Key Set](https://auth0.com/docs/jwks). If the token is valid, the request is allowed to continue. Otherwise, the server returns a 401 Unauthorized response.
153129

154130
### Set up a proxy to the backend API
155131

0 commit comments

Comments
 (0)