Tutorial

Embed dashboard with a silent login via Auth0

  • 20 May 2022
  • 0 replies
  • 105 views
Embed dashboard with a silent login via Auth0

This article extends the article Embed dashboard with a silent login via Okta SSO. We will show you how to embed GoodData.CN Dashboard to custom React.js application with a silent login via Auth0. Before we dive into the problem, let me just say that I am running GoodData.CN and React.js application on my computer — therefore, all API requests are to localhost.

Step 1: Create Auth0 Application for GoodData.CN

For successful SSO, we need to create a new application in the Auth0 manage section.

  1. Select Applications in the left panel.

     

  2. Click the Create Application button and select Regular Web Application.

     

  3. Fill up Allowed Callback URLs, Allowed Web Origins, and Allowed Origins (CORS).

     

For the Allowed Callback URLs it is important to fill up the correct URL https://<organization-hostname>/login/oauth2/code/<organization-hostname>. In our case, where we run GoodData.CN locally, the URL is http:/localhost:3000/login/oauth2/code/localhost. For the rest (allowed web origins and CORS), we can simply fill up http://localhost:3000.

Step 2: Map Auth0 user in GoodData.CN

Let’s map the Auth0 user to GoodData.CN with two simple API calls (you can find all the necessary information in the application created in the first step). 

  1. The first one updates the OIDC settings of the organization.
    $ curl --request PUT \
    --header "Authorization: Bearer $GDC_API_TOKEN" \
    --header 'Content-Type: application/vnd.gooddata.api+json' \
    --data '{
    "data": {
    "id": "default",
    "type": "organization",
    "attributes": {
    "name": "GoodData.CN - Auth Test",
    "hostname": "localhost",
    "oauthIssuerLocation": "https://<your-issuer-url>/",
    "oauthClientId": "<your-client-id>",
    "oauthClientSecret": "<your-client-secret>"
    }
    }
    }' http://localhost:3000/api/entities/admin/organizations/default
    You can find all the necessary properties in the manage section of your application in Auth0. Do not forget to add slash “/” at the end of authIssuerLocation. Without the slash, it won’t work. 
  2. The second API call maps a user in the Identity Provider to the organization.
    $ curl --request POST \
    --header "Authorization: Bearer $GDC_API_TOKEN" \
    --header 'Content-Type: application/vnd.gooddata.api+json' \
    --data '{
    "data": {
    "id": "john.doe",
    "type": "user",
    "attributes": {
    "authenticationId": "<user-sub-claim>"
    },
    "relationships": {
    "userGroups": {
    "data": [ {
    "id": "adminGroup",
    "type": "userGroup"
    } ]
    }
    }
    }
    }' http://localhost:3000/api/entities/users

    You can find authenticationId in the user management section in Auth0. The authenticationId should has the following format auth0|<id>.

Now, you can visit http://localhost:3000, and you should be able login into GoodData.CN within Auth0. As mentioned, you can see that both API calls are against localhost. Suppose you do not run your GoodData.CN on your computer — just use your domain instead. You can find more information here: GoodData.CN external OIDC.

Step 3: React application with all necessary dependencies

If you already have an application where you use Auth0 as your Identity Provider, feel free to skip this section.

  1. Create react application.
    $ npx create-react-app gooddata-client
  2. Add all necessary dependencies.
    $ npm install @auth0/auth0-react react-router-dom@6

Now everything is ready. The application has all the necessary dependencies, and we can run npm start to start the application. We run GoodData.CN on port 3000 — due to this fact, we will need to run the react application on port 3001. After running the command npm start, the process will ask you if you want to start the react application on port 3001.

Step 4: Configuration of the react application in the Auth0 manage section

If you already have an application where you use Auth0 as your Identity Provider, feel free to skip this section. 

  1. Similar to Step 1, navigate to the Applications section and click the create application button. Instead of Regular Web Applications, select Single Page Web Applications.

     

  2. Fill up Allowed Callback URLs, Allowed Web Origins, and Allowed Origins (CORS).

     

Step 5: Connect everything together

  1. Add ProtectedRoute component (./src/ProtectedRoute.js).
    import React from "react";
    import { withAuthenticationRequired } from "@auth0/auth0-react";

    export const ProtectedRoute = ({ component, ...args }) => {
    const Component = withAuthenticationRequired(component, args);
    return <Component/>;
    };

     

  2. Add Auth0ProviderWithRedirectCallback component (./src/Auth0ProviderWithRedirectCallback.js).
    import React from "react";
    import { useNavigate } from "react-router-dom";
    import { Auth0Provider } from "@auth0/auth0-react";

    export const Auth0ProviderWithRedirectCallback = ({ children, ...props }) => {
    const navigate = useNavigate();
    const onRedirectCallback = (appState) => {
    navigate((appState && appState.returnTo) || window.location.pathname);
    };
    return (
    <Auth0Provider onRedirectCallback={onRedirectCallback} {...props}>
    {children}
    </Auth0Provider>
    );
    };

     

  3. Edit App component (./src/App.js).
    import React from "react";
    import "./App.css";
    import { useAuth0 } from "@auth0/auth0-react";

    function App() {
    const { logout } = useAuth0();
    return (
    <div style={{ display: "flex", height: "100%", width: "100%", justifyContent: "center", alignItems: "center" }}>
    <div>
    <div>Home</div>
    <button style={{marginTop: "10px"}} onClick={() => logout()}>Logout</button>
    </div>
    </div>
    );
    }

    export default App;

     

  4. Edit index (./src/index.js).
    import React from "react";
    import ReactDOM from "react-dom/client";
    import "./index.css";
    import App from "./App";
    import reportWebVitals from "./reportWebVitals";
    import { BrowserRouter, Route, Routes } from "react-router-dom";
    import { Auth0ProviderWithRedirectCallback } from "./Auth0ProviderWithRedirectCallback";
    import { ProtectedRoute } from "./ProtectedRoute";
    import Analytics from "./Analytics";

    const root = ReactDOM.createRoot(
    document.getElementById("root"),
    );
    root.render(
    <React.StrictMode>
    <BrowserRouter>
    <Auth0ProviderWithRedirectCallback
    domain="<your-auth0-domain>"
    clientId="<your-client-id>"
    redirectUri={window.location.origin}
    >
    <Routes>
    <Route path="/" element={<ProtectedRoute component={App}/>}/>

    </Routes>
    </Auth0ProviderWithRedirectCallback>
    </BrowserRouter>
    </React.StrictMode>,
    );

    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();

     

  5. Open the dashboard you want to embed, and in the right upper corner, click on the Embed button.

     

  6. Click the Copy Iframe button.

     

  7. Create Analytics component and put there copied Iframe (./src/Analytics.js).
    export default function Analytics() {
    return (
    <div>
    <div>Analytics</div>
    <iframe
    src="http://localhost:3000/dashboards/embedded/#/workspace/<your-workspace-id>/dashboard/<your-dashboard-id>?showNavigation=true&setHeight=700"
    height="700px" width="100%" frameBorder="0"></iframe>
    </div>
    );
    }
  8. Add the new Analytics component to the router (./src/index.js).
    <Route path="/analytics" element={<ProtectedRoute component={Analytics}/>}/>

Now, if you open http://localhost:3001/analytics, your application should now look like this (of course, with your dashboard).

You can try logout/login, and everything should be smooth. You just need to log in once to your react application. 


0 replies

Be the first to reply!

Reply