Skip to main content
Woohoo! Qlik Community has won “Best in Class Community” in the 2024 Khoros Kudos awards!
Announcements
Join us at Qlik Connect for 3 magical days of learning, networking,and inspiration! REGISTER TODAY and save!
Ouadie
Employee
Employee

In the last couple of posts, we explored qlik-embed, Qlik’s new library for embedding Qlik Sense analytics into web applications, and went over how to do silent authentication with OAuth. Since then, the library has seen some updates, and today, we’ll delve into a new feature that allows to embed charts that are created on the fly as well as look into how to handle anonymous access using OAuth impersonation.

  • What’s New in qlik-embed?

Charts on the Fly

One of the features that standout in the newest qlik-embed release is "charts on the fly." This allows you to create charts dynamically from data within a Qlik Sense app without needing the chart to pre-exist in the app itself.

Instead, you pass a chart definition including dimensions, measures, and chart properties, and qlik-embed generates it on the fly in your web app.

Here’s a quick example using qlik-embed web components:

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <style>
        .container {
            padding: 8px;
            gap: 8px;
            position: relative;
            flex: 1 0 auto;
            display: flex;
            flex-direction: column;
            align-items: stretch;
            box-sizing: border-box;
        }

        .viz {
            width: 600px;
            height: 600px;
            padding: 16px;
            border: 1px solid #bbb;
            border-radius: 3px;
            box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.2);
            position: relative;
        }
    </style>
    <title>@qlik/embed-web-components example - using OAuth</title>
    <script crossorigin="anonymous" type="application/javascript"
        src="https://cdn.jsdelivr.net/npm/@qlik/embed-web-components@1/dist/index.min.js"
        data-host="<YOUR TENANT>" data-client-id="<CLIENT ID>"
        data-redirect-uri="https://localhost:3000/index_oauth_object.html" data-access-token-storage="session"></script>
</head>

<body>
    <div id="main-app">
        <div class="container">
            <h1>@qlik/embed-web-components Example</h1>
        </div>
        <div id="analytics-chart" class="container">
            <h2>"qlik-embed" <em>analytics-chart</em> embedding chart on the fly.</h2>
            <div class="viz">
                <qlik-embed id="visualization" ui="analytics/chart" app-id="<THE APP ID>"
                    type="barchart" dimensions='["Type", "Experience"]' measures='["Count([Demo ID])"]'
                    properties='{ orientation: "horizontal", barGrouping: { grouping: "stacked" } }'
                    context___json='{ theme: "Breeze", interactions: { select: false } }'></qlik-embed>

            </div>
        </div>
</body>

</html>

 

 

This feature is particularly powerful for creating highly dynamic and responsive dashboards where the visualizations can adapt to the user's needs in real time. However, keep in mind that "charts on the fly" is currently limited to the chart types available in the analytics/chart UI within qlik-embed. You can refer to the chart compatibility table for the most up-to-date information.

Notice that you can now pass context using the context___json (triple underscores (___)) to apply a specific theme etc..

For instance:

 

<qlik-embed context___json='{ theme: "Breeze" }' ... />

 

 

  •  Understanding OAuth Impersonation

OAuth impersonation tokens in Qlik Cloud are a game-changer for web applications needing to access resources on behalf of users, especially when dealing with different identity providers. This method replaces the need for third-party cookies with OAuth tokens to maintain state, significantly improving security and user experience.

Things to keep in mind when using OAuth Impersonation:
  1. Do Not Expose Machine-to-Machine Clients on the Frontend: keep your client secrets in the backend.
  2. Use a Backend Web Application for Token Issuance: Create an endpoint in your backend application to issue tokens.
  3. Explicitly Set Scopes on Impersonation Tokens: Ensure your tokens have the minimal required scopes to enhance security.

Here’s an example snippet for issuing impersonation tokens using the @qlik/api library:

 

import { auth as qlikAuth, users as qlikUsers } from "@qlik/api";

const qlikConfig = {
  authType: "oauth2",
  host: "https://tenantName.region.qlikcloud.com",
  clientId: "OAuth impersonation client Id",
  clientSecret: "OAuth impersonation client secret",
};

//set the host configuration to talk to Qlik tenant
qlikAuth.setDefaultHostConfig(qlikConfig);

//access token method the frontend will call
app.post("/access-token", requiresAuth(), async (req, res) => {
  const userId = req.session?.user?.id;
  try {
    //call to Qlik Cloud tenant to obtain an access token
    const accessToken = await qlikAuth.getAccessToken({
      hostConfig: {
        ...qlikConfig,
        userId,
        noCache: true,
      },
    });
    console.log("I got an access token!");
    //access token returned to front end
    res.send(accessToken);
  } catch (err) {
    console.log(err);
    res.status(401).send("No access");
  }
});

 



Or using the fetch API:

 

const hostConfig = {
  host: "https://tenantName.region.qlikcloud.com",
};

const payload = {
  client_id: "OAuth impersonation client Id",
  client_secret: "OAuth impersonation client secret",
  grant_type: "urn:qlik:oauth:user-impersonation",
  user_lookup: {
    field: "subject",
    value: "SUBJECT_VALUE",
  },
  scope: "user_default",
};

async function getAccessToken(hostConfig, payload) {
  const getToken = await fetch(`${hostConfig.host}/oauth/token`, {
    method: "POST",
    mode: "cors",
    credentials: "include",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payload),
  });
  const response = await getToken.json();
  //console.log(response);
  return response;
}

(async () => {
  await getAccessToken(hostConfig, payload);
})();

 

 

Once you have the backend that generates the access token built, you can access it on the frontend in the qlik-embed library by using the "data-get-access-token" attribute and passing it the name of the function that calls your access token backend API endpoint, like this:

 

    <script crossorigin="anonymous" type="application/javascript"
        src="https://cdn.jsdelivr.net/npm/@qlik/embed-web-components@1/dist/index.min.js"
        data-host="<YOUR TENANT>" data-client-id="<YOUR CLIENT ID>"
        data-get-access-token="getAccessToken" data-auth-type="Oauth2"></script>

    <script>
        async function getAccessToken() {
            const response = await fetch("<BACKEND API URL>/access-token", {
                method: "POST",
                credentials: "include",
                redirect: "follow",
                mode: "cors"
            });
            if (response.status === 200) {
                const tokenResp = await response.json();
                const accessToken = tokenResp.access_token;
                return accessToken;
            }
            const err = new Error("Unexpected serverside authentication error");
            err.status = response.status;
            err.detail;
            throw err;
        }
    </script>

 



You can visit qlik.dev for more information about authentication concepts.

The qlik-embed library continues to evolve, bringing powerful new features and enhanced security capabilities to the table. Whether you're creating dynamic visualizations on the fly or implementing different auth methods, qlik-embed provides the tools needed for bring Qlik analytics into your web applications.