Securing the Whole App
In this lesson, we will use the token received after authentication to secure our AJAX calls.
In the last lesson, we received the token after having authenticated the user, and now we will be sending the token to all the components needing to make an authenticated AJAX request.
We will use RxJS Subject-observables here. We will create a BehaviorSubject
holding an initial value and send the received value using the next method of the Subject. This value will then be received by all the components subscribing to this observable at any point in time.
Too much theory? Let’s look at the code and try to understand this.
First step - We will save the received token in the service using a setter.
this._tokenService.setTokenVal(this_token);
In the service,
public setTokenVal(tokenValue) {
// send the token value using next on the Subject
}
Let’s create the subject now:
@Injectable({
providedIn: 'root'
})
export class TokenService {
private _tokenProviderSubject: BehaviorSubject<string>;
public tokenProviderObservable$: Observable<string>;
constructor(private _httpReqService: HttpRequestService, private _router: Router) {
this._tokenProviderSubject = new BehaviorSubject(null);
this.tokenProviderObservable$ = this._tokenProviderSubject.asObservable();
}
}
Notice closely here, in the same token service, we have created a BehaviorSubject
with a value of Type string
. We have also created an observable that will be subscribed to retrieve the data.
As per official docs, BehaviorSubject
is:
A variant of Subject that requires an initial value and emits its current value whenever it is subscribed to.
So, the next step is to initialize this Subject and observable inside the constructor.
So, we created _tokenProviderSubject
with an initial value of null and tokenProviderObservable$
as an observable of this subject created above. This line of code defines the association of this observable to this Subject.
Now, the task is to set the Subject value as the received token value in the next method. Inside the setTokenVal method, we will set the subject value as the token value.
public setTokenVal(tokenValue) {
this._tokenProviderSubject.next(tokenValue);
}
Now whichever component subscribes to this observable gets the latest tokenValue.
Until this step, our application has one value of the token received globally, and now we need to make it accessible to any component needing to make authenticated AJAX requests.
Now, take a scenario where as soon as the user is authenticated, they need to navigate to the dashboard, and the dashboard needs to make an AJAX request to take the user data (the authenticated user’s data).
In this case, we need to ensure that on the load of the Dashboard component, it should have the token available, and that is when it should perform the request to get the dashboard data.
Remember lifecycle hooks?
On the initialization of the view, ngOnInit()
lifecycle hook is invoked, so we want to get the token value in this lifecycle hook and also perform the request to get the dashboard data inside the ngOnInit()
lifecycle hook.
dashboard.component.ts
ngOnInit() {
this.getTokenValue();
}
public getTokenValue() {
this._tokenService.tokenProviderObservable$ .subscribe(this._getTokenValueHandler);
}
private _getTokenValueHandler = (data) => {
data === null && (
this._router.navigate(['/login']);
)
this._getDashboardData(data.student_id, data.token);
}
}
This is the last and most important piece of our authentication journey.
Here we are getting the token inside the ngOnInit()
lifecycle hook. Inside that getToken
method, we subscribe to the tokenProviderObservable$
and call the
_getTokenValueHandler
method. Inside the _getTokenValueHandler
method, we route the user to log in again as the data is null. However, if the token is found in the data, we know for sure that the user is authenticated and therefore, can be allowed to get the data by making an authenticated AJAX request to the server.
So, we finally call the _getDashboardData
method with the user id and the JWT token and perform the GET request.
An important thing to note is that in the HTTP request service, you would need to set the header as follows because the token is to be sent as a part of the header and not as the body.
private _getHttpHeaders(headerConfig) {
return new HttpHeaders({
'Content-Type': headerConfig && headerConfig.contentType ? headerConfig.contentType : 'application/json',
}).set('token-name', headerConfig && headerConfig.token ? headerConfig.token : '')
}
And this is all to get your authentication working. Let’s look at a working example.
Get hands-on with 1400+ tech skills courses.