This is a follow up post of “Securing your Angular 7+ application with OIDC and NgRx”. We’ll be building in this example right on top of the previously created DraftApp. If you want to follow along but skip the initialization of the Angular App, grab the code from GitHub and continue right away:
https://github.com/alx-andru/draft
A major motivation to build ng-oidc-client was to combine oidc-client with NgRx to bring authentication into application state. Doing so we can now take advantage of effects and and be able to respond to state changes in a reactive way within our entire application.
Let’s first have a look at all the OidcActions that ng-oidc-client provides us with:
User/Identity related actions
- GetOidcUser
- RemoveOidcUser
- UserExpired
- UserFound *
- OnUserLoading
- UserDoneLoading
- UserLoadingError
UserManager events from oidc-client
- OnUserLoaded
- OnUserUnloaded
- OnAccessTokenExpiring
- OnAccessTokenExpired
- OnSilentRenewError
- OnUserSignedOut *
- OnSessionChanged
Signin/-out
- SigninPopup
- SigninRedirect
- SigninSilent
- SignInError
- SignoutPopup
- SignoutRedirect
- SignOutError
Errors
- OidcError
Most likely you will never have the urge or need to use the majority of the available actions as ng-oidc-client takes care of the authentication and uses these actions internally. However, it is entirely up to you and your use case. We’ll have a look at some practical examples of using effects in our application.
Reacting to a user sign-out from the Identity Provider
The action OnUserSignedOut can be easily used to determine if a user has signed out from the Identity Provider. In our minimal example we’re redirecting the user from his current state back to the HomeComponent. Depending on your application you might just want to notify the user with a dialog to sign-in again or be redirected to a different route.
Using angular cli we can create a new service called OidcEffectsService
ng g s effects/OidcEffects
and add a new Effect to it
As our effect only uses the router to navigate back to the HomeComponent, there is no need to dispatch any further actions, which is why we set dispatch to false.
Before we can test out our Effect we have to add it to the EffectsModule in our app.module.ts
...
EffectsModule.forRoot([OidcEffectsService]),
...
If we now look at the Identity Provider and our application side by side, we should see that as soon as we sign-out from the Identity Provider, our application automatically reacts to it and redirects the now signed-out user back to the HomeComponent.
In addition to this, we could also register a dedicated reducer as a Meta Reducer in our StoreModule that will reset the entire application state if the user has signed out. Information and data displayed to the user won’t remain on the screen if the user decided to sign-out.
If you’d like to read more about Meta Reducers have a look at the article Implementing a Meta-Reducer in ngrx/store
The Meta Reducer has to be registered in the StoreModule in our app.module.ts
...
StoreModule.forRoot({}, { metaReducers }),
...
Prompt user to continue session
The actions OnAccessTokenExpiring and OnAccessTokenExpired, in combination with the configuration setting:
NgOidcClientModule.forRoot({
oidc_config: {
...
automaticSilentRenew: false,
}
}),
The token won’t be renewed when it expires, but thanks to the actions, we get notified about it and our application can react to it.
Augment user information once user is loaded
Your service might provide additional, application specific information about the user, beyond the available data in your Identity Provider. You could use the UserFound action to load this additional information as illustrated in the following example:
Keep exploring the capabilities of the library:
Feel free to leave comments with any questions, feedback or ideas 🙌 …