Json Web Token Authentication for Angular App with Auth0 and RESTHeart

Riccardo Corti
SoftInstigate Team
Published in
8 min readJul 24, 2019

In this tutorial we will see how to create an Angular application that uses the Auth0 service to manage user authentication and RESTHeart to create APIs for authenticated users via Json Web Token.

Auth0 is a universal authentication & authorization platform for web, mobile and legacy applications.

RESTHeart connects to MongoDB and exposes a simple REST API to read and write data via plain HTTP requests.

The article is divided into three parts.

  1. Auth0 configuration. We create an Auth0 application from their site and we take the data necessary to configure RESTHeart and the Angular application.
  2. RESTHeart configuration with JWT Authorizer. We configure the backend using RESTHeart with the Json Web Token Authentication mechanism.
  3. Angular App configuration with auth0.js: We create the frontend using an Angular application that authenticates users via Auth0 and makes a call to the backend with the JWT returned by Auth0.

The frontend is responsible for authenticating users by calling Auth0 and generating the JWT that is used to make authenticated calls to RESTHeart.

The following diagram summarizes the high-level flow for reading / writing data.

1. Auth0 configuration

Let’s go to the Auth0 website to register and access the control dashboard.

We create a new application by clicking on the “Create Application” button and choose “Angular” as the frontend technology.

Access the settings of the app we have just created.

At this stage we must take the necessary steps to configure our Angular app and RESTHeart.

The parameters we need to configure the Angular application are:

  1. Client ID.
  2. Client Domain.
  3. Audience.

The parameters we need to configure RESTHeart are:

  1. Client ID.
  2. Certified key to decrypt the JWT that is generated by Auth0 (with RS256 algorithm).

To see the certified key we need to click on “Show Advanced Settings” and go to the “Certificates” menu:

As a final step, we insert the “Allowed Callback URLs”

http://localhost:4200/callback

and “Allowed Web Origins”

http://localhost:4200

on the settings page of our application. This allows us to use Auth0 services directly in our local environment.

Now we have everything we need to configure RESTHeart and the Angular App, let’s see how.

2. RESTHeart configuration with the JWT Authorizer

The commercial version of RESTHeart 4 provides authentication via the Json Web Token mechanism.

Download RESTHeart (you will receive an email with a trial license key) and run the setup as indicated in the official documentation.

To enable the JWT frame authentication mechanism we need to modify the security configuration file, which is

etc/restheart-platform-security.yml 

Uncomment the jwtAuthenticationMechanism configuration section and insert the following parameters:

  • algorithm: RS256 (it is the algorithm used by default by Auth0 to generate the JWT)
  • key: enter the Certified Key
  • issuer: enter the Domain
  • audience: enter the Client ID

This is our configuration:

- name: basicAuthMechanism
class: org.restheart.security.plugins.mechanisms.BasicAuthMechanism
args:
realm: RESTHeart Realm
authenticator: rhAuthenticator
- name: jwtAuthenticationMechanism
class: com.restheart.security.plugins.mechanisms.JwtAuthenticationMechanism
args:
algorithm: RS256
key: MIIDBTCCAe2gAwIBAgIJeXcI+Z6tmSW3MA0GCSqGSIb3DQEBCwUAMCAxHjAcBgNVBAMTFXJoLWp3dC10ZXN0LmF1dGgwLmNvbTAeFw0xOTA2MDQwODExMTRaFw0zMzAyMTAwODExMTRaMCAxHjAcBgNVBAMTFXJoLWp3dC10ZXN0LmF1dGgwLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC...
base64Encoded: false
usernameClaim: email
# rolesClaim:
fixedRoles:
- admin
issuer: https://rh-jwt-test.auth0.com/
audience: nFeKEybdTeO0c9MrM2gCeTg4viXN4iNF

Save the file and edit docker-compose.yml to overwrite the default restheart-platform-security.yml file in the container with the modified one, as follows (note that we added a new volume)

 services:
restheart-platform-security:
image: softinstigate/restheart-platform-security
container_name: restheart-platform-security
build:
context: ./
dockerfile: ./Docker/Dockerfile-security
depends_on:
- restheart-platform-core
networks:
- backend
volumes:
- ./security.log:/var/log/restheart-platform-security.log:rw
- ./etc/restheart-platform-security.yml:/opt/restheart-platform/etc/restheart-platform-security.yml:ro
ports:
- "8080:8080"

and run RESTHeart with the docker-compose command:

and run RESTHeart with the docker-compose command:

docker-compose up -d

We can tail the container logs with the docker command:

$ docker-compose logs -f...restheart-platform-core                | *-------------------------------------------------------------------*
restheart-platform-core | | |
restheart-platform-core | | This instance of RESTHeart is licenced under the Terms and |
restheart-platform-core | | Conditions of the Commercial License Agreement. |
restheart-platform-core | | |
restheart-platform-core | *-------------------------------------------------------------------*
restheart-platform-core |
restheart-platform-core | 07:48:54.772 [main] INFO com.restheart.CommLicense - The License Agreement is available at /opt/restheart-platform/lickey/COMM-LICENSE.txt
restheart-platform-core | 07:48:54.880 [main] INFO org.restheart.Bootstrapper - RESTHeart started

Let’s create a dragons collection:

$ http -a admin:secret PUT http://localhost:8080/dragonsHTTP/1.1 201 Created
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location, ETag, X-Powered-By
Auth-Token: 29exjnfasaacst1ym7yxq59jn361fpuxo72lopivsox39o243s
Auth-Token-Location: /tokens/admin
Auth-Token-Valid-Until: 2019-07-19T08:25:00.028324Z
Connection: keep-alive
Content-Length: 0
Content-Type: application/json
Date: Fri, 19 Jul 2019 08:10:00 GMT
ETag: 5d317ad88bee1d5c49537088
X-Powered-By: restheart.org

let’s populate it with some documents:

$ echo '[{"name":"Smaug"},{"name": "Spyro"}, {"name":"Shenrom"},{"name":"Mushu"}]' | http -a admin:secret POST http://localhost:8080/dragonsHTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location, ETag, X-Powered-By
Auth-Token: 29exjnfasaacst1ym7yxq59jn361fpuxo72lopivsox39o243s
Auth-Token-Location: /tokens/admin
Auth-Token-Valid-Until: 2019-07-19T08:30:09.377320Z
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 131
Content-Type: application/json
Date: Fri, 19 Jul 2019 08:15:09 GMT
ETag: 5d317c0d8bee1d5c4953708a
X-Powered-By: restheart.org
{
"_links": {
"rh:newdoc": [
{
"href": "/dragons/5d317c0d8bee1d5c4953708b"
},
{
"href": "/dragons/5d317c0d8bee1d5c4953708c"
},
{
"href": "/dragons/5d317c0d8bee1d5c4953708d"
},
{
"href": "/dragons/5d317c0d8bee1d5c4953708e"
}
]
},
"deleted": 0,
"inserted": 4,
"matched": 0,
"modified": 0
}

Note that RESTHeart is started also with the Basic Authentication active, we can disable it. Let’s comment-out the Basic Authentication mechanism from the configuration file

etc/restheart-platform-security.yml 

the new configuration is:

# - name: basicAuthMechanism
# class: org.restheart.security.plugins.mechanisms.BasicAuthMechanism
# args:
# realm: RESTHeart Realm
# authenticator: rhAuthenticator
- name: jwtAuthenticationMechanism
class: com.restheart.security.plugins.mechanisms.JwtAuthenticationMechanism
args:
algorithm: RS256
key: MIIDBTCCAe2gAwIBAgIJeXcI+Z6tmSW3MA0GCSqGSIb3DQEBCwUAMCAxHjAcBgNVBAMTFXJoLWp3dC10ZXN0LmF1dGgwLmNvbTAeFw0xOTA2MDQwODExMTRaFw0zMzAyMTAwODExMTRaMCAxHjAcBgNVBAMTFXJoLWp3dC10ZXN0LmF1dGgwLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC...
base64Encoded: false
usernameClaim: email
# rolesClaim:
fixedRoles:
- admin
issuer: https://rh-jwt-test.auth0.com/
audience: nFeKEybdTeO0c9MrM2gCeTg4viXN4iNF

stop and relaunch the Docker containers:

$ docker-compose stopStopping restheart-platform-security ... done
Stopping restheart-platform-core ... done
Stopping restheart-platform-mongodb ... done
$ docker-compose up -d --build

RESTHeart is configured properly and ready to be used.

3. Angular App configuration with auth0.js

In this tutorial we use a demo application made available by Auth0 that we have modified to call our backend directly after users have authenticated.

You can find the fork of the application at this repository.

To configure the Angular app we modify the enviroments / enviroments.ts file, insert the following parameters:

  • CLIENT_ID: the Client Id;
  • CLIENT_DOMAIN: the Domain
  • AUDIENCE: the Audience
  • REDIRECT: the redirect url after authentication
  • LOGOUT_URL: the redirect url after logout
  • RESTHEART_URL: the RESTHeart url

This is our configuration:

export const environment = {
production: false,
auth: {
CLIENT_ID: 'nFeKEybdTeO0c9MrM2gCeTg4viXN4iNF',
CLIENT_DOMAIN: 'rh-jwt-test.auth0.com',
AUDIENCE: 'rh-jwt-api',
REDIRECT: 'http://localhost:4200/callback',
LOGOUT_URL: 'http://localhost:4200',
RESTHEART_URL: 'http://localhost:8080'
}
};

The application uses the api of the auth0.js library to manage user authentication and a custom angular service to make calls to the RESTHeart backend.

The service that calls RESTHeart is very simple:

@Injectable()
export class ApiService {
constructor(private http: HttpClient) { }
getDragons$(idToken: String): Observable<any[]> {
return this.http
.get<any[]>(environment.auth.RESTHEART_URL + '/dragons')
.pipe(
catchError(err => throwError(err))
);
}
}

All calls made to the backend have an interceptor that adds the Bearer header to the JWT token.

@Injectable()
export class InterceptorService implements HttpInterceptor {
constructor(private auth: AuthService) { }
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return this.auth.idToken$
.pipe(
filter(token => typeof token === 'string'),
mergeMap(token => {
const tokenReq = req.clone({
setHeaders: { Authorization: `Bearer ${token}` }
});
return next.handle(tokenReq);
})
);
}
}

Let’s run our application :

npm install & ng serve

Our application is now visible at http://localhost: 4200, here’s how it appears:

Clicking on the Log In button we will be redirected to the Auth0 Universal Login interface from which we can register a new user in the Sign Up section.

Let’s register and login, once inside we’ll see some information about our profile and the JWT returned by Auth0.

By clicking on the Call RESTHeart link, the Angular application will perform a GET on the collection dragons and display all the documents returned, in this way:

Users who register correctly in our Application (whether using a username and password or via OAuth Google) are saved in Auth0. From the Dashboard you can see all registered users by going to the appropriate Users section. In our case we see that there is only the user we have previously registered.

Conclusions

The management of users in an Angular application becomes relatively simple if it is demanded to an external service such as Auth0. All user management operations (login, logout, forgot password, change password, email validation, etc.) are provided by Auth0, we do not have to worry about implementing from scratch.

This allows us to focus on the heart of our application and on the features we want to make available by our APIs.

To access the APIs users will also need to authenticate to the backend, this operation is very simple if you use the JWT authentication mechanism provided by RESTHeart 4.

It will be sufficient to authenticate using Auth0 to receive the JWT to be used for RESTHeart calls and be able to authenticate in full security.

--

--