Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 
dnordstrom
Contributor II
Contributor II

Enigma.js/WebSockets Authorization for Qlik Sense Enterprise on Cloud Services

We've set up QSE on Cloud Services with Auth0 as our IdP. We can successfully show charts with the Visualization API, but we'd like to build charts with Picasso.js in our React application, using the QdtComponents (which we monkey patched to add support for web integrations ID) and Enigma.js.

We can successfully authenticate with Auth0 and receive an access token in our Node.js backend. I'm just not sure what to do with this token to authorize Enigma.js's WebSockets requests. We currently get an 401 Unauthorized response.

Anyone know how we can use the Engine API with Enigma.js from our React application with QSE for Cloud Services?

Labels (5)
9 Replies
mek
Employee
Employee

How to provide the credentials depends on whether you're creating the socket in nodejs or in the browser as they differ slightly.

For the nodejs side you need an API key which you then provide as a header.

For the web you need a web integration id and also fetch the csrf token, you can see an implementation of it here 

dnordstrom
Contributor II
Contributor II
Author

It's a React app, so it's client-side/browser using Enigma.js. As far as I can understand, you can't set headers for WebSocket requests in the browser.

Does Enigma.js make use of web integration ID and CSRF tokens? If so, how?

Getting a CSRF token for use with Fetch is not a problem. It's WebSocket requests and Enigma.js.

andree_hansson
Employee
Employee

Hi!

I can see now that our documentation is not really clear and it's been in our backlog to extend https://github.com/qlik-oss/web-integration-examples/tree/master/app-reloader to showcase the websocket since it's a bit unique because of exactly what you're saying, in the browser you cannot control the headers of websockets.

TL;DR what you need is:

* A web integration id

* A CSRF token

And in your websocket URL, plug those in like so:

wss://hostname/app/guid?qlik-web-integration-id=foo&qlik-csrf-token=bar

 

Hope that helps!

dnordstrom
Contributor II
Contributor II
Author

Yes, my man! That's all I needed, hopefully, will try it out.

Thank you, much appreciated!

dnordstrom
Contributor II
Contributor II
Author

Apparently, it was easier said than done.

From our Node.js backend, I'm doing a request for an access token from Auth0. Works great. Then I use that access token to immediately fetch a CSRF token that I can use for WebSockets on the frontend. Still in Node.js, I'm doing a GET request to https://ouraccount.eu.qlikcloud.com/v1/csrf-token with the access token as authorization header (I assume I should do this):

 

 

const response = await fetch(
    'https://ouraccount.eu.qlikcloud.com/v1/csrf-token',
    {
      method: 'GET',
      cache: 'no-cache',
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    },
  );

 

 

All I get back is an HTML page. I've tried using application/json as content type, same result.

andree_hansson
Employee
Employee

Hey, you're missing /api in your URL: https://ouraccount.eu.qlikcloud.com/api/v1/csrf-token

The token will be accessible in a header, mind you, not the body.

But when you're mentioning Auth0 I'm getting curious, at this point, you cannot use client credentials grant tokens to consume websockets since those are service-to-service JWTs, and you need either a browser session or an API key for an end-user to consume websockets (just want to confirm this is what you're trying to do).

dnordstrom
Contributor II
Contributor II
Author

Hi there. Thanks a lot, /api in the URL moves things along a bit, now we're getting a response saying "No token found". An improvement!

What we want to do: say we have an intranet-like application (separate JS backend and frontend) where we handle our own login flow and have our own user accounts. We'd simply like to display charts with Enigma.js/Picasso.js, without sending the user through another OAuth flow.

So we figured we'd authenticate on backend with our client and secret, machine to machine with the credentials grant flow. Now we have an access token. Then I was told we need a CSRF token as well, and to set them as URL parameters for the WebSockets requests. We're trying to fetch it in our backend with node-fetch, but we might do it in the browser later, doesn't matter to me.

That's where we are now. I'm just not sure how to get Enigma and Picasso (preferably through QdtComponents) working with a machine to machine flow without interaction from the user.

The plan would be to adjust the QdtComponents for React to set these URL parameters, which it then sends to Enigma, which then creates the socket. If necessary we can fork Enigma to make adjustments as well.

Maybe it's simpler than I realize, who knows. The documentation is lacking, outdated, and incredibly confusing at times.

 

 

dnordstrom
Contributor II
Contributor II
Author

The only way I can get a CSRF token is if I'm logged into Qlik and do the request in the browser so the appropriate cookies are sent along. Is there no way to display Picasso charts from Qlik Sense on Cloud without having the user log in interactively?

thomaspessato
Partner - Contributor
Partner - Contributor

Hey! Did you manage to solve your problem? I'm having the same issue. But I'm using Oauth to do it. Cannot do get to csrf-token URL, so I cannot connect properly to enigma, etc.