Step 1. Define the API endpoint
We will use the Express web application framework to build our Node.js API.Create a package.json File
Create a folder for your API, navigate into it and runnpm init
. This will set up your package.json
file.
You can leave the default settings or change them as you see fit.
Our sample’s package.json
looks like the following:
Install the Dependencies
Next, we need to set our dependencies. We will use the following modules:- express: This module adds the Express web application framework.
- jwks-rsa: This library retrieves RSA signing keys from a JWKS (JSON Web Key Set) endpoint. Using
expressJwtSecret
we can generate a secret provider that will provide the right signing key toexpress-jwt
based on thekid
in the header. For more information refer to the node-jwks-rsa GitHub repository. - express-jwt: This module lets you authenticate HTTP requests using JWT tokens in your Node.js applications. It provides several functions that make working with JWTs easier. For more information refer to the express-jwt GitHub repository.
- body-parser: This is a Node.js body parsing middleware. It extracts the entire body portion of an incoming request stream and exposes it on
req.body
as something easier to interface with.For more information and several alternatives refer to the body-parser GitHub repository.
Implement the Endpoint
Navigate to your API directory and create aserver.js
file. Your code needs to:
- Set the dependencies.
- Enable the request body parsing middleware.
- Implement the endpoint.
- Launch the API server.
node server
and make an HTTP POST request to localhost:8080/timesheets/upload
. You should see a JSON response with a message This is the POST /timesheets/upload endpoint
.
So now we have our endpoint but anyone can call it. Continue to the next paragraph to see how we can fix this.
Step 2. Secure the API endpoint
In order to validate our token we will use thejwt
function, provided by the express-jwt middleware, and the jwks-rsa
package to retrieve the public key from Auth0. The libraries do the following:
express-jwt
will decode the token and pass the request, the header and the payload tojwksRsa.expressJwtSecret
.jwks-rsa
will then download all signing keys from the JWKS endpoint and see if a one of the signing keys matches thekid
in the header of the JWT. If none of the signing keys match the incomingkid
, an error will be thrown. If we have a match, we will pass the right signing key toexpress-jwt
.express-jwt
will continue its own logic to validate the signature of the token, the expiration,audience
and theissuer
.
- Create the middleware function to validate the .
- Enable the use of the middleware in our routes.
localhost:8080/timesheets/upload
we should get the error message Missing or invalid token
(which is perfectly fine since we didn’t send an access token in our request).
In order to test the working scenario as well we need to:
- Get an access token. For details on how to do so refer to: Get an Access Token
- Invoke the API while adding an
Authorization
header to our request with the valueBearer ACCESS_TOKEN
(whereACCESS_TOKEN
is the value of the token we retrieved in the first step).
Step 3. Check the Client permissions
In this step we will add to our implementation the ability to check if the client has permissions (orscope
) to use our endpoint in order to upload a timesheet. In particular we want to ensure that the token has the correct scope, which is batch:upload
.
In order to do this we will make use of the express-jwt-authz
Node.js package, so go ahead and add that to your project:
jwtAuthz(...)
to your middleware to ensure that the JWT contains a particular scope in order to execute a particular endpoint. This is our sample implementation (some code is omitted for brevity):
403
. You can test this by removing this scope from your API.
That’s it! You are done!