Skip to main content

React SDK

Overview#

A common problem for React front-ends is to conditionally display UI elements based on the set of permissions that the logged-in user possesses. For example, if a user only has "viewer" permissions, the front-end typically wants to avoid displaying UI elements that allow users to edit or update resources.

Aserto addresses this problem by defining the display state map pattern.

The Aserto React SDK works together with other high-level language SDKs like the Express.js to allow retrieving this display state map when the user logs in (and/or reload it). This in turn can be used to instruct the UI on whether to render specific UI elements that correspond to these routes / permissions.

Credits#

Loosely modeled after the Auth0 React SDK.

This SDK uses the Aserto javascript SPA SDK.

Github#

This SDK is open source and can be found on GitHub.

Installation#

Using npm:

npm install @aserto/aserto-react

Using yarn:

yarn add @aserto/aserto-react

Getting Started#

Configure the SDK by wrapping your application in AsertoProvider. If using in conjunction with the Auth0Provider, AsertoProvider should be nested inside of it.

// src/index.tsximport React from 'react'import ReactDOM from 'react-dom'import { AsertoProvider } from '@aserto/aserto-react'import { Auth0Provider } from '@auth0/auth0-react'import App from './App'
ReactDOM.render(  <Auth0Provider    domain="YOUR_AUTH0_DOMAIN"    clientId="YOUR_AUTH0_CLIENT_ID"    redirectUri={window.location.origin}  >    <AsertoProvider>      <App />    </AsertoProvider>  </Auth0Provider>,  document.getElementById('app'));

Use the useAserto hook in your components to initialize (init), reload the display state map (reload) or to access its state (loading, displayStateMap, getDisplayState, etc):

// src/App.jsimport React from 'react'import { useAserto } from '@aserto/aserto-react'import { useAuth0 } from '@auth0/auth0-react'
function App() {  const {    loading,         // true while the state is loading    isLoaded,        // true if the displayStateMap was loaded    error,           // error object (if initOptions.throwOnError is false)    identity,        // identity header to send to displaystatemap call    setIdentity,     // set the identity header    displayStateMap, // display state map    getDisplayState, // getDisplayState() function (see below)    init,            // init() function (see below)    reload           // reload() function (see below)  } = useAserto();
  // the Aserto hook needs a valid access token.  // to use Auth0 to return an access token, you can use the following:  const { isLoading, isAuthenticated, getAccessTokenSilently } = useAuth0();
  // use an effect to load the Aserto display state map  useEffect(() => {    async function load() {      const token = await getAccessTokenSilently();      if (token) {        await init({ accessToken: token });      }    }
    // load the display state map when Auth0 has finished initializing    if (!isLoading && isAuthenticated) {      load();    }  // eslint-disable-next-line react-hooks/exhaustive-deps  }, [isAuthenticated]);
  if (loading) {    return <div>Loading...</div>;  }
  if (error) {    return <div>Error: {error}</div>;  } else {    return (      <div>        {          // output the display state map as a string          displayStateMap        }      </div>    );  }}
export default App

init()#

Initialize the Aserto client.

const { init, displayStateMap } = useAserto();await init({  serviceUrl: 'http://service-url', // defaults to windows.location.origin  endpointName: '/__displaystatemap', // defaults to '/__displaystatemap'  accessToken: '<VALID ACCESS TOKEN>', // REQUIRED  throwOnError: true, // true: re-throw errors. false: set error object. defaults to true.  defaultDisplayState: { // an optional default display state (default values below)    visible: false,    enabled: false  }});
// log the display state map to the consoleconsole.log(displayStateMap);

reload(headers)#

Re-load the display state map for a service that exposes it. If the headers parameter is passed in, it is passed through to the AsertoClient instance that will retrieve the display state map from the API endpoint.

Note: init() must be called before reload().

const { reload, displayStateMap } = useAserto();await reload();
// log the display state map to the consoleconsole.log(displayStateMap);

identity and setIdentity#

  • setIdentity can be used to set the identity to pass as an identity HTTP header. It will override an identity header that is passed into reload(headers). This is the preferred way to send an identity to the displayStateMap API, which can be used to override the Authorization header by the displayStateMap middleware.
  • identity will return the current identity (or undefined if it hasn't been set).

getDisplayState('method, 'path')#

Retrieves a displayState associated with a specific resource.

By convention, the method argument is an HTTP method (GET, POST, PUT, DELETE), and the path argument is in the form /path/to/resource. It may contain a __id component to indicate an parameter - for example, /mycars/__id.

If only the method argument is passed in, it is assumed to be a key into the displayStateMap (typically in the form of METHOD/path/to/resource).

The returned map will be in the following format:

{  visible: true,  enabled: false,}

Note: init() must be called before getDisplayState().

const { getDisplayState } = useAserto();const path = '/api/path';
// retrieve visibility of an elementconst isVisible = aserto.getDisplayState('GET', path).visible;
// determine whether an update operation is enabledconst isUpdateEnabled = aserto.getDisplayState('PUT', path).enabled;
// print out display state values for each verb on a resourcefor (const verb of ['GET', 'POST', 'PUT', 'DELETE']) {  const resource = aserto.getDisplayState(verb, path));  for (const value of ['visible', 'enabled']) {    console.log(`${verb} ${path} ${value} is ${resource[verb][value]}`);  }}