In this tutorial, you will integrate with Auth0 to authenticate users of your app. You will use authentication to secure the dashboard portion of your web component as well as the HTTP endpoints of the API component. To do this, you will first configure Auth0, then make changes to your app and test it locally, and finally re-deploy the secured application to AWS. Upon completion, you will be able to log in to the dashboard portion of your web component using your Google Account:

This tutorial assumes you have already made the first deployment of your application to AWS, and then completed one full development cycle including re-deploying your application to AWS. Let's get started!
Run the following command:
$ yarn ops status -a web
...
Web
Service
Status RUNNING
Health HTTP 200 (206ms)
Url https://uxb9hhcrtj.us-west-2.awsapprunner.com
...
Take note of the Url value, which is the public HTTPS URL of your website. Let's call it base Url - we will be using it when configuring Auth0 in the next steps.
We are going to be using Auth0 as the third-party authentication provider. If you don't have an Auth0 account, you can create one here.
Go to the Applications / APIs section of the Auth0 management portal and create a new API. Give it a Name you like and set the Identifier to letsgo:service
(this is important):

Once the Auth0 API is created, go to its settings, turn on Allow Offline Access, and Save the change:

Next, in the Auth0 management portal, go to the Applications / Applications section and create a new application. Give it a Name you like and choose Regular Web Application for the application type.

Once the Auth0 application has been created, go to its settings, find the Basic Information section, and take note of the following values: Domain, Client ID, and Client Secret. We will be using them later when configuring your LetsGo application.

On the same settings page, find the Application URIs section, and make the following changes:
- In Allowed Callback URLs, enter two URLs separated by a comma:
http://localhost:3000/api/auth/callback
{base-url}/api/auth/callback
, where{base-url}
is the base URL of your website you obtained by runningyarn ops status -a web
before
- In Allowed logout URLs and in the Allowed Web Origins, enter two URLs separated by a comma:
http://localhost:3000
- the base URL of your website

Scroll down the page and Save the changes.
While you are at the bottom of the page, expand Advanced Settings, go to the Endpoints tab, and take note of the JSON Web Key Set value. It will look similar to https://goletsgo.us.auth0.com/.well-known/jwks.json
. We will be using this URL in the next steps when instructing your LetsGo application to trust Auth0 as an authentication provider.
Add the following environment variables to the apps/web/.env.local
file in your project:
cat >> apps/web/.env.local <<EOF
AUTH0_ISSUER_BASE_URL=https://{auth0-domain}
AUTH0_CLIENT_ID={auth0-client-id}
AUTH0_CLIENT_SECRET={auth0-client-secret}
AUTH0_SECRET={auth0-secret}
AUTH0_AUDIENCE=letsgo:service
AUTH0_SCOPE=openid profile email offline_access
AUTH0_BASE_URL=http://localhost:3000
EOF
Remember to substitute the Domain, Client ID, and Client Secret values from the previous step for {auth0-domain}
, {auth0-client-id}
, and {auth0-client-secret}
, respectively.
For {auth0-secret}
, generate a random password - this is the key that will be used to encrypt Auth0 cookies when you run your app locally. You can run node -p "Math.random().toString(32).substring(2)"
to quickly generate a pseudo-random value which should be good enough for the purpose.
Run the following command to register your Auth0 tenant as a trusted authentication provider:
yarn ops issuer add --issuer https://{auth0-domain}/ --jwks {json-web-key-set-url}
Remember to substitute Domain and JSON Web Key Set URL for {auth0-domain}
and {json-web-key-set-url}
, respectively.
NOTE Take note of the trailing slash in the value of the --issuer
option. For example, your command to register an Auth0 issuer will look similar to:
yarn ops issuer add --issuer https://goletsgo.us.auth0.com/ --jwks https://goletsgo.us.auth0.com/.well-known/jwks.json
Start your application locally with:
yarn dev
Then navigate to http://localhost:3000
in the browser and click the Login link in the navbar. You should be redirected to Auth0 and see the Auth0 login dialog:

From here, you can choose to log in using your Google Account or choose Sign up to create a new username and password for your app. After a successful login, you will be redirected back to your locally running application. You will see a page that is part of the management dashboard of your application only available to authenticated users. Sections of this page allow you to manage certain settings of the tenant of your application which was created when you first logged in:

Now that you have authentication working locally, you will configure and re-deploy your app to AWS.
Run the following commands to configure Auth0 for the deployment of your app in AWS:
yarn ops config set AUTH0_ISSUER_BASE_URL=https://{auth0-domain}
yarn ops config set AUTH0_CLIENT_ID={auth-client-id}
yarn ops config set AUTH0_CLIENT_SECRET={auth0-client-secret}
Remember to substitute the Domain, Client ID, and Client Secret values from the previous step for {auth0-domain}
, {auth0-client-id}
, and {auth0-client-secret}
, respectively.
For those configuration changes to take effect, you need to re-deploy your application with:
yarn ops deploy -a all
Once the deployment command is completed, navigate the browser to the public URL of your website (which you can obtain by running yarn ops status -a web
), and click the Login link in the navbar. You should be taken through the same login flow as you just tested locally. After login, you will be redirected to the same tenant management page you have seen locally.
At this point, the API component of your app can also leverage the trust relationship with Auth0 to authenticate callers. To demonstrate it, we will call a secure API endpoint of your app with and without an access token issued by Auth0.
First, start your application locally unless it is already running:
yarn dev
Then, call the /v1/me
API of your local API server without providing an access token:
$ curl http://localhost:3001/v1/me
{"statusCode":401,"message":"Unauthorized"}
Notice how the call was rejected with an HTTP 401 response.
Now, let's get the access token we can use. Go to the Auth0 management portal, navigate to Applications / APIs, locate the Auth0 API you have previously created and enter it, go to the Test tab, and locate the Sending the token to the API section at the bottom. You should see a template of a curl
command similar to this:
curl --request GET \
--url http://path_to_your_api/ \
--header 'authorization: Bearer eyJhbGciOiJSUzI1NiIsIn....8qXcLuBk9hdb1RFdQ'
The ey...
string in the authorization
header will be quite a bit longer. It is your access token issued by Auth0. Copy and modify the command by replacing http://path_to_your_api/
with http://localhost:3001/v1/me
, then execute the command:
$ curl --request GET \
> --url http://localhost:3001/v1/me \
> --header 'authorization: Bearer eyJhbGciOi...31JX_NE2nAzwI2zyvW8qXcLuBk9hdb1RFdQ'
You will see the output similar to this:
{
"identityId": "idn-6874747073253341253246253246676f6c657473676f2e75732e61757468302e636f6d2532463a4250525a386b626a6d6a315332787253306932646a336f456236626b6561786e253430636c69656e7473",
"identity": {
"iss": "https://goletsgo.us.auth0.com/",
"sub": "BPRZ8kbjmj1S2xrS0i2dj3oEb6bkeaxn@clients"
},
"tenants": [
{
"tenantId": "ten-d54feabe077948e1af2d97f2e8668b0e",
"displayName": "Pink Swallow",
"createdAt": "2023-11-07T22:14:18.446Z",
"createdBy": {
"iss": "https://goletsgo.us.auth0.com/",
"sub": "BPRZ8kbjmj1S2xrS0i2dj3oEb6bkeaxn@clients"
},
"updatedAt": "2023-11-07T22:14:18.446Z",
"updatedBy": {
"iss": "https://goletsgo.us.auth0.com/",
"sub": "BPRZ8kbjmj1S2xrS0i2dj3oEb6bkeaxn@clients"
},
"plan": {
"planId": "free",
"changes": [
{
"timestamp": "2023-11-07T22:14:18.446Z",
"updatedBy": {
"iss": "https://goletsgo.us.auth0.com/",
"sub": "BPRZ8kbjmj1S2xrS0i2dj3oEb6bkeaxn@clients"
},
"newPlanId": "free"
}
]
}
}
]
}
The HTTP 200 response indicates the API call was successful. The access token presented was trusted by the API. In the JSON response, the /v1/me
endpoint returns information about the tenants of your app the caller has permissions to.
You can try issuing the same request to the public API endpoint of your app, which you can get by running yarn ops status -a api
.
Congratulations! You have successfully secured access to your web and API components using Auth0. Users of your app will need to log in to your dashboard using Auth0, and they will need to obtain an access token from Auth0 in order to call the HTTP APIs.
From here, you can choose to integrate Stripe to offer paid subscriptions or configure a custom domain for your app.