Embed Qlik Sense & Qlik Answers using qlik-embed and emulated SSO (Single Sign On) via OAuth impersonation
Important
This project is not production ready. It is structured for learning and evaluation of the qlik-embed project with a simple OAuth impersonation configuration. For a production app, you should first review the guiding principles for OAuth impersonation and understand how to use qlik-embed and qlik/api. You should also use HTTPS rather than HTTP for your project.
Note
Consider first reviewing the associated embed Qlik Analytics tutorial before you begin.
The goal of this project is to show how to easily deploy analytics & AI into your solution with a seamless login experience for your users, even when your web app or portal doesn't have a backend identity provider for users to authenticate to directly. This project leverages Qlik's qlik-embed, qlik/api, and OAuth machine-to-machine impersonation capabilities.
It showcases several embedding techniques, such as:
- qlik-embed
classic/app: full sheet embed supporting the native experience - qlik-embed
analytics/sheet: lightweight full sheet embed - qlik-embed
classic/chart: load legacy charts in a similar manner toclassic/app - qlik-embed
analytics/chart: lightweight charts in a similar manner toanalytics/sheet - qlik-embed
analytics/charton-the-fly: lightweight charts generated on-the-fly (e.g. the chart doesn't need to be in the Qlik Sense app, it is defined in the web app instead) - qlik-embed
ai/agentic-assistant: provides access to the Qlik Answers agentic assistant that works across both structured and unstructured data - qlik-embed
ai/assistant(legacy): provides access to the legacy unstructured AI assistants in Qlik Answers - qlik-embed
analytics/field: lightweight way to render a list box containing dimension values - qlik-embed
analytics/selections: lightweight way to render a full Qlik Sense selections bar - qlik-embed retrieval of hypercube data from an existing object
- qlik/api retrieval of hypercube data without an existing qlik-embed object
- Node.js version 20 or higher
- An OAuth M2M client for the backend calls, configured with:
- Scopes:
user_default,admin_classic - Allowed origins:
http://localhost:3000
- Scopes:
- An OAuth M2M impersonation client for the frontend calls, configured with:
- Scopes:
user_default - Allowed origins:
http://localhost:3000
- Scopes:
Clone the GitHub repository using the git clone command.
git clone https://github.com/qlik-oss/qlik-cloud-embed-oauth-impersonation.gitAlternatively, you can download and extract the project files.
- On the project's GitHub page, click Code.
- Select Download ZIP.
- Extract the content of the ZIP file in the folder of your choice.
- Upload the demo Qlik Sense app to your tenant.
- Open the app and copy the ID (it will be a GUID similar to
946d5af4-e089-42d3-9ba7-1d21adb68472).This demo contains some hard-coded values which will only work with this Qlik Sense app.
- Move the app into a new
sharedspace. - Edit the space configuration to provide
Can viewaccess to anyone in the tenant.In a production deployment, you would verify that the logged-in user has access to the app.
- Follow the Qlik Answers help documentation to set up a new Knowledgebase and Assistant, and index the knowledgebase data ready for users to ask questions.
- Provide
ViewandCan consume dataroles to all users in the tenant for the spaces containing the knowledgebase, assistant, and any data connections used by the knowledgebase. - Note the assistant GUID — you can use it as either
AGENTIC_ASSISTANT_ID(for the agentic assistant UIai/agentic-assistant) orASSISTANT_ID(for the legacy assistant UIai/assistant), or both if you have separate assistants.
- Rename the
template.envfile to.env. - Edit the
.envfile with values that match your Qlik Cloud deployment:OAUTH_BACKEND_CLIENT_IDandOAUTH_BACKEND_CLIENT_SECRET: enter the credentials obtained when you created the OAuth M2M client in the Administration activity center.OAUTH_FRONTEND_CLIENT_IDandOAUTH_FRONTEND_CLIENT_SECRET: enter the credentials obtained when you created the OAuth M2M impersonation client in the Administration activity center.Keep these secrets safe as they provide wide access to your tenant.
TENANT_URI: enter the hostname of the Qlik Cloud tenant against which the app will run, such asz29kgagw312sl0g.eu.qlikcloud.com.APP_ID: enter the app GUID for the Qlik Sense app you uploaded to your tenant (used for analytics/sheet, classic/app, analytics/chart and classic/chart examples).AGENTIC_ASSISTANT_ID: enter the GUID of the Qlik Answers agentic assistant for theai/agentic-assistantUI, or leave blank to omit.ASSISTANT_ID: enter the GUID of the Qlik Answers Assistant you wish to embed with the legacyai/assistantUI, or leave blank to omit.
- (Optional) If you are using an app other than the provided Qlik Sense application,
configure the following:
SHEET_ID: a sheet ID from your app (used for the analytics/sheet and classic/app examples).OBJECT_ID: a chart (object) ID from your app (used for the analytics/chart and classic/chart examples).FIELD_ID: a field from your app (used for the filter pane example).HYPERCUBE_DIMENSION: a field to use as a dimension for the hypercube (data) example.HYPERCUBE_MEASURE: a measure expression to use as a measure for the hypercube (data) example.MASTER_DIMENSION: a master dimension name used for the on-the-fly example.MASTER_MEASURE: a master measure name used for the on-the-fly example.
- (Optional) If you wish to further configure your web app and integration, update:
SESSION_SECRET: enter a random long string that will be used to sign the session.PORT: specify the port the web app will be hosted app when you run it withnpm start.USER_PREFIX: enter the prefix that new users will be created with when logging into the web app.
-
Open a terminal window and navigate to the folder containing the project files you extracted or cloned.
cd <project-folder>
-
Install the project dependencies.
npm install
-
Start the development server:
npm start
-
Open http://localhost:3000 in your browser.
You should see your web app running locally.
This demo uses two separate OAuth clients to keep credentials scoped to their intended purpose:
Browser Node.js server (server.js) Qlik Cloud
│ │ │
│ 1. POST /login (email) │ │
│──────────────────────────────────>│ │
│ │ 2. Look up / create user │
│ │ (Backend M2M client) │
│ │──────────────────────────────>│
│ │<──────────────────────────────│
│ 3. Serve home.html │ │
│<──────────────────────────────────│ │
│ │ │
│ 4. POST /access-token │ │
│──────────────────────────────────>│ │
│ │ 5. Mint impersonation token │
│ │ (Frontend M2M client) │
│ │──────────────────────────────>│
│ │<──────────────────────────────│
│ 6. Token returned to browser │ │
│<──────────────────────────────────│ │
│ │ │
│ 7. qlik-embed uses token to │ │
│ render analytics directly │ │
│──────────────────────────────────────────────────────────────────>│
| OAuth client | Configured with | Used for |
|---|---|---|
Backend M2M (admin_classic, user_default) |
OAUTH_BACKEND_CLIENT_ID / SECRET |
Server-side: look up and create Qlik users. Credentials never leave the server. |
Frontend M2M impersonation (user_default) |
OAUTH_FRONTEND_CLIENT_ID / SECRET |
Server-side: mint short-lived tokens that impersonate a specific user. Tokens are passed to the browser for use by qlik-embed. |
The browser never sees the OAuth client secrets. It only ever receives a short-lived access token that it passes to qlik-embed via the data-get-access-token callback.
├── server.js # Express backend: auth flow, user provisioning, API routes
├── template.env # Copy to .env and fill in your credentials
├── src/
│ ├── home.html # Main dashboard — all qlik-embed examples in one page
│ ├── login.html # Demo login form (email only, no real auth)
│ ├── js/
│ │ └── script.js # Frontend helpers: getAccessToken, getConfig, getSheets, getHypercube
│ └── css/
│ └── qlik-embed-style.css # Layout styles for embed containers
└── tests/ # Playwright end-to-end tests
Key entry points for reading the code:
server.jslines 45–93 — the two OAuth configs and thegetFrontendHostConfig()helperserver.jsPOST /access-token— how a user-scoped token is minted on each requestserver.jsGET /— how a Qlik user is looked up or created on first loginsrc/js/script.jsgetAccessToken()— the callbackqlik-embedcalls for tokenssrc/home.htmlupdateHeaders()— howqlik-embedis loaded and configuredsrc/home.htmlupdateQlikEmbedTags()— how app/sheet/object IDs are set at runtime
The project includes Playwright end-to-end tests that verify authentication and content rendering. Tests require a configured .env file pointing at a live Qlik Cloud tenant.
# Run all tests (headless)
npm test
# Watch tests run in a real browser
npm test -- --headed
# Open the interactive Playwright UI
npm test -- --ui
# View the HTML test report after a run
npm run test:report