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
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:
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 AngularHttpClient
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
We change the session data using the
We create a provider, which will return a
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
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
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 thecanActivate
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
Post a Comment