@genesislcap/foundation-auth
v14.227.3
Published
Genesis Foundation Auth
Downloads
5,252
Readme
Foundation Auth
foundation-auth
is a fully featured authentication micro frontend that is http and cookies based. It allows your
application to provide a more efficient and secure authentication experience, and enables functionality like popout
windows. The package differs from foundation-login
which authenticated over websockets and is now considered
deprecated.
foundation-auth
provides several exports to promote reuse and extensibility at various levels. These include but are
not limited to:
ZeroAuth
: A preconfigured version of the micro frontend built with the zero design system and zero components.configure
: A customisation hook for the base micro frontend that integrates it with your design system of choice.AuthStore
: An auth based foundation-store.AuthMachine
: An auth based foundation-state-machine covering the various auth workflows.AuthMessageMapper
: The auth message dto to entity mapper.AuthRouting
: A routing utility, which you can callnavigateTo(...)
to navigate to internal routes.- Various UI components / route screens, some of which are lazy loaded on-demand to optimise the experience.
For applications that do not or cannot use the DI system, we export utility functions to get each from the DI container.
For example, getAuthStore
, getAuthMachine
, getAuthRouting
etc.
Many of these are available as subpath exports and should be imported from these to optimise bundling and overall efficiency.
import { configure } from '@genesislcap/foundation-auth/configure';
import { AuthRouting } from '@genesislcap/foundation-auth/routing';
// note zero is on the root export
import { ZeroAuth } from '@genesislcap/foundation-auth';
In most cases, developers simply import the ZeroAuth
micro frontend, or use the configure
export
token to tailor the micro frontend to their specific needs in their router config. However, developers can also use the
exports provided to build their own authentication frontends or workflows. A set of pre-defined custom events are used
to interact with the AuthStore
and AuthMachine
, and developers can provide custom implementations of parts of the
machine's workflow.
Basic setup instructions
These examples are based on a host application using FAST and the FASTRouter. However, setup in the frontend and router of your choice should be quite similar.
Environment variables
foundation-auth
uses the following environment variables. The .env
file below shows the built-in defaults used with API_HOST
.
# There should be nothing sensitive here!
# HTTP
GENX_LOGIN_URL=/sm/event-login-auth
GENX_LOGIN_REFRESH_URL=/sm/event-login-auth
GENX_LOGIN_DETAILS_URL=/sm/event-login-details
GENX_LOGOUT_URL=/sm/event-logout
GENX_CHANGE_PASSWORD_URL=/sm/event-change-user-password
GENX_FORGOT_PASSWORD_URL=/sm/event-self-service-password-reset
GENX_RESET_PASSWORD_URL=/sm/event-password-reset-action
# SSO (type and id will be replaced on runtime idp selection)
GENX_SSO_LIST_URL=/sm/sso/list
GENX_SSO_LOGIN_URL=/sm/{type}/login?idp={id}
If you are happy with these defaults then you have nothing more to do.
Here is an example of loading environment variables contained in a .env
file into a webpack build, but how you set
environment variables at an app level is really up to you.
const { resolveDefineConfig } = require('@genesislcap/build-kit'); // < npm install @genesislcap/build-kit --save
const { config } = require('dotenv'); // < npm install dotenv --save
const { DefinePlugin } = require('webpack');
config(); // < loads the .env vars
module.exports = {
...
plugins: [
new DefinePlugin(resolveDefineConfig(['GENX_*'])), // < code replacement should include 'API_HOST' if set, ie. ['GENX_*', 'API_HOST', ...]
],
}
Set up a route to host the micro frontend
Here we are lazy loading the micro frontend when the route is accessed.
{
title: 'Authenticate',
name: 'auth',
path: 'auth', // < at what path should the micro frontend be accessed. Could be an empty string, ie. on the website root.
element: async () => {
const { configure } = await import('@genesislcap/foundation-auth/config');
return configure({
omitRoutes: ['request-account'],
hostPath: 'auth', // < important to match the route path
logo: myLogo,
background: myBG,
postLoginRedirect: () => {
// You could inspect the user here and route them based on various conditions.
Route.path.push('my-dashboard');
},
});
},
childRouters: true,
settings: { public: true },
layout: authLayout,
}
Checking the user authentication status during routing
Here in our FASTRouter
's NavigationContributor
, we check the user status as part of the routing flow.
import { User } from '@genesislcap/foundation-user';
...
@User private user: User;
...
this.contributors.push({
navigate: async (phase) => {
const settings = phase.route.settings;
/**
* Don't block public routes or any routes when authenticated
*/
if (settings?.public || this.user.isAuthenticated) {
return;
}
/**
* Otherwise route them to auth
*/
phase.cancel(() => {
this.user.trackPath(); // < Track the user's path to return to it post login if required
Route.name.replace(phase.router, 'auth');
});
},
});
Establishing a Websocket Connection
Creating an actual websocket connection to the Genesis backend is beyond the scope of foundation-auth
. Post login you
can import the API_HOST
from @genesislcap/foundation-utils
and connect to the Genesis backend. Below uses connect
from the DI container.
import { API_HOST } from '@genesislcap/foundation-utils';
...
@Connect private connect: Connect,
...
this.connect.connect(API_HOST);
Logging out
You can logout easily by navigating to the logout route. To help, you can access the AuthRouting
singleton via the DI
container from anywhere in your app, such as a header's logout button, and call navigateTo
.
import { AuthRouting } from '@genesislcap/foundation-auth/routing';
...
@AuthRouting private authRouting: AuthRouting;
...
this.authRouting.navigateTo('logout');
...or via a utility if your app is not using decorators or the DI container.
import { getAuthRouting } from '@genesislcap/foundation-auth/routing';
...
private authRouting = getAuthRouting();
...
this.authRouting.navigateTo('logout');
You can use AuthRouting
to navigate to other routes, like change password etc., without needing to know the full
path the micro frontend is hosted on.
If you have trouble logging out using the routing utility, you can try using your host app's router directly.
The following example is Angular based, where the developer has put the micro frontend on the auth
path. There's logic
within the micro frontend that will automatically navigate itself to the logout route if the login screen is loaded
while the user is already logged in. Logging out is as easy as moving back to that route.
import { Router } from '@angular/router';
export class AppComponent {
constructor(private router: Router) {}
/**
* Note the developer has put the micro frontend of the `auth` path.
*/
onLogout() {
/**
* Navigate back to the micro frontend and it will take care of the logout.
*/
this.router.navigateByUrl('auth');
/**
* Alternatively, you can navigate to the internal logout route.
* this.router.navigateByUrl('auth/logout');
*/
}
}
See the AuthRouting API Docs for more information.
API Docs
Troubleshooting
- We're using
foundation-login
, do we have to move tofoundation-auth
?foundation-login
authenticated over websockets and is now considered deprecated, but it will still work for the time being. Moving is advised and should be pretty seamless.
- We're using
configure
but are not seeing our changes reflected?- Ensure you're importing
configure
from the/config
subpath and not the root of the package. - Ensure you're not importing anything from the root of the package elsewhere in your application.
- Ensure you're importing
- The
Forgot Password?
,Change Password
andRequest Account
links don't seem to do anything.- If you're hosting the micro frontend on anything other than the top level root path
''
, for example:path: 'auth'
, then ensure thehostPath
property in theconfigure
matches.
- If you're hosting the micro frontend on anything other than the top level root path
Installation
To enable this module in your application, follow the steps below.
- Add
@genesislcap/foundation-auth
as a dependency in yourpackage.json
file. Whenever you change the dependencies of your project, ensure you run the$ npm run bootstrap
command again. You can find more information in the package.json basics page.
{
...
"dependencies": {
...
"@genesislcap/foundation-auth": "latest"
...
},
...
}
API Docs
License
Note: this project provides front-end dependencies and uses licensed components listed in the next section; thus, licenses for those components are required during development. Contact Genesis Global for more details.
Licensed components
Genesis low-code platform