Authentication and Authorization with Angular 2+

In this tutorial, I'll show you how you can secure your Angular 2+ application. Please, take a look at my previous post (Authorization and Authentication with AngularJS + Jersey) for the backend implementation. 

1. Authentication mechanism

We use JWT (JSON Web Token) authentication mechanism in our application. We have decided to store our JWT in a cookie with HttpOnly (prevent XSS attacks) and Secure (sent over HTTPS only).

In order to prevent CSRF attack we'll use the double submit cookie.  This pattern is defined as sending a random value in both a cookie and as a request header. When a user authenticates to our application via the login page, the API responds with 2 cookies:
  • A cookie (XSRF-TOKEN) set with a strong random value with Secure flag only.  We will instruct Angular HttpClient to read this value and set it as an HTTP header (X-XSRF-TOKEN) for each subsequent request. Since only JavaScript that runs on your domain can read the cookie, your server can be assured that the XHR came from JavaScript running on your domain.
  • A cookie set with our JWT which includes the strong random value (xsrfToken) as a claim.  This cookie is not accessible through JavaScript as explained above. On the server side, a filter checks if the X-XSRF-TOKEN and the xsrfToken match.

2. Authentication Service



2.1 Session Data

Our session data will be stored in our authentication service. We use BehaviorSubject from RxJS. The whole point of using RxJS is to asynchronously update and share session data across our application. This is done by subscribing to the Observable in our components as follow :


We change the session data using the next method of the BehaviorSubject inside our helper methods setAuthentication and purgeAuthentication.

2.2 Populate Method

Because we cannot access our JWT cookie from JavaScript, we need to load the session data from an API during initialization of the application.

We create a provider, which will return a Promise, which will be resolved when the request completed. Our populate function will be executed at application initialization process. This function will retrieve and set our session data.

We need a factory in order to hook into app init process and load the session data when csrf cookie is available.


We instruct Angular to use it in the init process with APP_INITIALIZER inside the providers section of your @NgModule.


2.3 Login

When no session data are available (no cookies, or expired cookies), the application prompts the user to enter his credentials. The server returns the user data along with the authentication cookies when the credentials match.

2.4 Logout

When the user logout, the server invalidate the authentication cookies.

3. Guards

In order to protect a route, we use the canActivate type, which is run before you navigate to a route. Our authentication guard will check if the user is valid otherwise it will navigate to the login route. It also grabs the current URL which will be set as a query parameter.


Now, we can attach this guard to our route:

The last task is to redirect the user after login, which is handled in the login component.

So, it's done. We have a pretty good foundation for implementing a reliable authentication process in our Angular application.

Don't hesitate to leave your comments or maybe to improve my solution.

Thanks

Comments

Popular posts from this blog

Spring JPA : Using Specification with Projection

Chip input using Reactive Form