Connecting to Zus from a Single Page Application

This tutorial will guide you through setting up a Single Page Application App Client and connecting to Zus, allowing your app to read and write data to Zus.

You can try out steps 1-2 below in the Zus Health API Postman collection by navigating to the Single Page App Client Creation Guide in the Auth & Permissions folder.

Step 1: Create an App Client in the Auth Service

Create app client documentation

POST https://api.sandbox.zusapi.com/auth/app-clients

{
    "data": {
        "type": "auth/app-clients",
        "attributes": {
            "type": "single_page_application",
            "name": "{{AppClientName}}",
            "userType": "builder"
        }
    }
}

Save the id and clientId of your app client from the response body.

Step 2: Update your App Client's settings

Now that you have created an app client, you can adjust the settings based on your application needs using the modify app client settings endpoint. For example, you may need to set the allowed callback URLs, login URL, logout URL and for your application. See the modify app client endpoint page for documentation on all app client settings that can be modified.

In this example we will update the allowed callback URLs, login URL and logout URL.

PATCH https://api.sandbox.zusapi.com/auth/app-clients/{{your-app-client-id}}/settings

{
     "data": {
          "type": "auth/app-client-settings",
          "attributes": {
               "allowedCallbackURLs": [
                    "https://yourappurl.com"
               ],
               "allowedLogoutURLs": [
                    "https://yourappurl.com/logout"
               ],
               "appLoginURI": "https://yourappurl.com/login", 
               "allowedWebOrigins": [
                    "https://yourappurl.com"
               ], 
               "tokenEndpointAuthMethod": "none"
          }
     }
}

Step 3: Use a React library to implement authorization flow

Single Page Applications should use a library to implement the Authorization Code Flow with Proof Key for Code Exchange (PKCE) to request a Zus access token. Below is a React example using the Auth0 React SDK:

Set up:

import React from 'react';
import ReactDOM from 'react-dom';
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}
		audience="https://api.sandbox.zusapi.com"
		useRefreshTokens=true
  >
    <App />
  </Auth0Provider>,
  document.getElementById('app')
);

Note: by setting useRefreshTokens in the Auth0Provider your app will utilize refresh tokens when your token expires.

Step 4: Add authentication mechanism

The next step is to add logic to authenticate to your application client that was created in step 1. This can be done again making use of the auth0 library.

function App() {
  const {
    isLoading,
    isAuthenticated,
    error,
    loginWithRedirect,
  } = useAuth0();

  if (isLoading) {
    return <div>Loading...</div>;
  }
  if (error) {
    return <div>Oops... {error.message}</div>;
  }

  if (isAuthenticated) {
    return (
      <Fragment>
        <div>
            Hello!
        </div>
        <AppClientList />
      </Fragment>
    );
  } else {
    return <button onClick={loginWithRedirect}>Log in</button>;
  }
}

export default App;

Step 5: Make HTTP requests to the Zus API with your access token

Follow the auth0 example to get an access token then make a request to the Zus API with your token in the Authorization header.

import React, { useEffect, useState } from 'react';
import { useAuth0 } from '@auth0/auth0-react';

const APP_CLIENT_ID = "YOUR_APP_CLIENT_ID"; 

const AppClientList = () => {
  const { getAccessTokenSilently } = useAuth0();
  const [ state, setState ] = useState({
      appClientJSON: ""
  });

  useEffect(() => {
    (async () => {
      try {
        const token = await getAccessTokenSilently();
        console.log(token)
        const response = await fetch('https://api.dev.zusapi.com/auth/app-clients/'+APP_CLIENT_ID, {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        });
        var res = await response.json();
        const newState = {...state}
        setState({
            ...newState, 
            appClientJSON: JSON.stringify(res),
        })
      } catch (e) {
        console.error(e);
      }
    })();
  }, [getAccessTokenSilently]);

  return (
    <p>
            {state.appClientJSON}
    </p>
  );
};

export default AppClientList;