Updating NgRx Auth effects

Now, let's handle all the asynchronous actions that need to be done while authenticating. First, we need a login effect that will call the authenticate method on Auth0's auth object. Next, when our callback page has been loaded with the parameters, we need to handle the login callback. We've already created a login observable that wraps the logic of parsing the hash parameters and getting the Auth results, which it then uses to store an Auth token and expiry in localStorage. Lastly, we will have a logout effect, which just removes the Auth token and expiry from localStorage and redirects us to the Home page.

Let's add our first effect for login, login$, which listens for the Login action and then calls Auth0's authorize method, which will open a new tab with an Auth0 sign-in page where the users will log in, as follows:

...
import { map, catchError, } from 'rxjs/operators';
import { AuthPartialState, AUTH_FEATURE_KEY, AuthState } from './auth.reducer'
;

import {
Login,
AuthActionTypes

} from './auth.actions';
import { State, Store } from '@ngrx/store';

@Injectable()
export class AuthEffects {

@Effect() login$ =
this.dataPersistence.fetch(AuthActionTypes.Login, {
run: (action: Login, state: AuthPartialState) => {
state[AUTH_FEATURE_KEY].auth.authorize();
},
onError: (err) => {
console.error(err);
}
}
);

...

}

Next, let's add another effect for logout. This effect will basically remove access tokens and expiration from localStorage and use the router to go to the default route of the application:

import { Router } from '@angular/router';
...

export class AuthEffects {
...
@Effect() logout$ = this.dataPersistence.fetch(AuthActionTypes.Logout,
{
run: () => {
localStorage.removeItem('access_token');
localStorage.removeItem('exp');
this.router.navigate(['']);
},
onError: () => {}
}
);

constructor(
...
private router: Router
) {}

}

The last effect we will add is for handleLoginCallback$, which will be called by the callback component we will be creating in the next section. We will get the hash code on this callback URL, which we will parse and get the Auth token for, and persist it in localStorage. Based on the success or failure of the authentication, we will route the user to successUrl or failureUrl, respectively, as follows:

...
import { bindNodeCallback, of, Observable } from 'rxjs';

import {
...
LoginSuccess,
LoginFailure,
HandleLoginCallback
} from './auth.actions';
import { Router } from '@angular/router';

...
export class AuthEffects {
onAuthSuccessUrl = '/';
onAuthFailureUrl = '/'
;
...

@Effect() handleLoginCallback$ =
this.dataPersistence.fetch(AuthActionTypes.HandleLoginCallback, {
run: (action: HandleLoginCallback, state: AuthPartialState) => {
return this.loginObservable$(state).pipe(
map(token => {
this.router.navigate([this.onAuthSuccessUrl]);
return new LoginSuccess();
}),
catchError(() => {
this.router.navigate([this.onAuthFailureUrl]);
return of(new LoginFailure());
})
);
},
onError: () => {}
});


parseHash$ = (state: any) => bindNodeCallback(state[AUTH_FEATURE_KEY].auth.parseHash.bind(state[AUTH_FEATURE_KEY].auth));

loginObservable$ = (state) => Observable.create((observer) => {
if (window.location.hash && !state[AUTH_FEATURE_KEY].authenticated) {
this.parseHash$(state)().subscribe({
next: (authResult: any) => {
localStorage.setItem('access_token',
authResult.idToken);
localStorage.setItem('exp',
authResult.idTokenPayload.exp);
observer.next();
},

error: err => {
console.error('Error', err);
observer.error(err);
}
});
}
}
)
}

Now that we have our NgRx actions, reducers, and action creators ready, let's go ahead and add the callback route to our Auth application to complete the authentication implementation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.51.3