Skip to main content
Announcements
Qlik Connect 2024! Seize endless possibilities! LEARN MORE
cancel
Showing results for 
Search instead for 
Did you mean: 
d_pranskus
Partner - Creator III
Partner - Creator III

Mashup with ticket authentication

Hi

I am building an mashup application which uses QlikSense tickets for authentication. I have a back end service which runs on different port, is trusted on QS server and I request tickets through it. To authenticate on the front end am using the following steps:

1. Request a ticket.

2. Use ticket to load a png file from Qlik Sense server. This stores a cookie in the browser

3. Load require.js and Qlik Styles from the server.

4. Load qlik object and use it to open the app.

Everything seems to be working perfectly if I use a new ticket every time I reload a page. But what I would like to do is to reuse the cookie (if one exists) instead of recreating it every time. Bu when I try to do that, I am unable to download the png file, and then all the rest requests are failing too, even the QS security cookie exists. Possibly the cross domain (because of different port) requests I do with axios are not using the existing cookie, even when the withCredentials option is set.

My front end app runs on port 8080, backend on 3000 and QlikSens runs on 443. Therefore I am facing cross domain request issues.

Following is a slightly simplified code I am using for this., Could someone give me some hints how to deal with that. Thank you.

 

import axios from 'axios';

const qlikConfig = {
    host: 'server',
    port: 443,
    secure: true,
    prefix: '',
    appId: ',,,',
    urlParams: {},
};

const getTicket = () => {
    // Placeholder for getTicket function
    return 'ticket';
};

const connectToQS = async () => {
    const baseUrl = 'https://server';

    const axiosApp = axios.create({
        withCredentials: true,
    });

    let connected = false;

    // try to connect without ticket. My intention here is, if this succeeds then the cookie exists,
    // just reuse it
    // this is actually failing returning the authentication page
    try {
        const response = await axiosApp.get(`${baseUrl}/img/core/dark_noise_16x16.png`);
        if (response.headers['content-type'] !== 'text/html') {
            connected = true;
        }
    } catch (err) {
        console.log(err);
    }

    // if connected go to loading qliksense and styles
    // if not, request for a ticket and usi it to set a cookie
    // This nbeeds to be run every time, and then everything works
    if (!connected) {
        try {
            const ticket = getTicket();
            await axiosApp.get(`${baseUrl}/img/core/dark_noise_16x16.png?qlikTicket=${ticket}`);
        } catch (err) {
            console.log(err);
        }
    }

    // add require.js to the document
    const requireTag = document.createElement('script');
    requireTag.type = 'text/javascript';
    requireTag.src=`${baseUrl}/assets/external/requirejs/require.js`;
    requireTag.id = 'qliksense-require-tag';
    document.head.appendChild(requireTag);
    requireTag.loaded = new Promise((resolve) => {
        requireTag.onload = () => {
            resolve();
        };
    });

    // add qlik style to the document
    const styleTag = document.createElement('link');
    styleTag.type = 'text/css';
    styleTag.rel = 'stylesheet';
    styleTag.href = `${baseUrl}/autogenerated/qlik-styles.css`;
    styleTag.id = 'qliksense-styles-tag';
    document.head.appendChild(styleTag);
    styleTag.loaded = new Promise((resolve) => {
        styleTag.onload = () => {
            console.log(`End 2 style ${Date()}`);
            resolve();
        };
    });

    // wait until require.js and
    await Promise.all([styleTag.loaded, requireTag.loaded]);

    window.require.config({
        baseUrl,
        paths: {
            qlik: `${baseUrl}/js/qlik.js`,
        },
        config: {
            text: {
                useXhr() {
                    return true;
                },
            },
        },
    });
    window.require(['js/qlik'], async (qlik) => {
        const appConfig = {
            host: qlikConfig.host,
            port: qlikConfig.port,
            isSecure: qlikConfig.secure,
            prefix: qlikConfig.prefix,
        };
        const app = qlik.openApp(qlikConfig.appId, appConfig);
    });
};

 

 

 

Labels (2)
2 Replies
ExperiaCare
Partner - Contributor II
Partner - Contributor II

Hello, 

 

I hope you managed to solve your issue. I am also running through the same challenges. It would be great if you can share more information on how you did overcome this issue (if you did). 

Thanks.

will_br
Contributor III
Contributor III

HI @d_pranskus  and @ExperiaCare ,

the solution we have here is basically the one described by @d_pranskus .

The only difference is that on the mashup we are using JWT authentication and the cookie lasts for the time defined on the proxy -- We do make a new request for the png file when the page reloads (probably unnecessary?) but we do not when we switch from one qlik app to another (it's a SPA).

--

Using the recent February Qlik version, in a separate tool we got, I only got the ticket authentication working using enigma.js. It's hard to rely on a third-party library that we don't know for how long it will be around but it seems pretty solid.

They have some pretty straightforward examples and the one using tickets worked almost instantly: https://github.com/qlik-oss/enigma.js/tree/master/examples/authentication/sense-using-ticket