Skip to main content
Announcements
Qlik Connect 2024! Seize endless possibilities! LEARN MORE
cancel
Showing results for 
Search instead for 
Did you mean: 
Poh
Contributor II
Contributor II

Qlik Sense Server: Using Javascript to authenticate users with JWT (401 error)

Hi, 

Mod Header is used in the article below to inject the JWT Bearer Token as an "Authorization" header to log into Qliksense. But I would like to do the same through Javascript.

https://community.qlik.com/t5/Official-Support-Articles/Qlik-Sense-How-to-set-up-JWT-authentication/...

I coded a test webpage with a button which when a user clicks will route the users to my qlik sense URL and authenticate them with JWT.

** to test the authentication I hardcoded the token.

Below is a sample of my code:

<button onclick="getResponse()">Click Here</button>
<script type = "text/javascript">
    function getResponse() {
    var url = "https://qliksense/jwt/hub";
    var token = "xxx";
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.setRequestHeader('Content-Type','application/json');
    xhr.setRequestHeader('Accept','application/json');
    xhr.setRequestHeader('Authorization',token);
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          console.log(xhr.responseText);
          window.location.href = url;
        }
      } else {
        console.error(xhr.status);
      }
    };
    };

Although my call is from a local host to the server I did not receive a CORS error. My header was also injected but still cant seem to log in. I used a valid token but I still got a 401 error. I could use the same token to login with my ModHeader extension.

Any one has any idea how to resolve it?

Labels (4)
7 Replies
alex_colombo
Employee
Employee

Hi @Poh aure you specifying the Bearer before the token? Like: Authorization: `Bearer ${token}`. Could you also try to add localhost and your port in QMC to your jwt virtual proxy configuration under allowed host list?

Poh
Contributor II
Contributor II
Author

Hi @alex_colombo ,

Yes, I am specifying the Bearer before the token.

I have also added the white list in the Advanced section of my jwt virtual proxy.

localhost:9000/test.html

*test.html is my html file which i code my button in

In addition I also added the additional response headers

Access-Control-Allow-Origin:*

Access-Control-Allow-Methods:*

Access-Control-Allow-Headers: Content-Type;Accept;Authorization

However I am still receiving a 401 error.

alex_colombo
Employee
Employee

Please define only this localhost:9000 without your html page and remove all the additional response headers, they are not necesseray.
Could you please post:

  • Payload used for generate the token
  • A screenshot of the GET call made by JS code with JWT token attached to the header (you can use browser developer tool) 
  • A screenshot of the GET call made by mod header with JWT token attached to the header (you can use browser developer tool) 
Poh
Contributor II
Contributor II
Author

Hi @alex_colombo 

I have changed it the whitelist to just localhost:9000 and have removed all additional header response. However, I am still facing the same error.

Please see below for the requested screenshots:

1. 

payload = {
    userID: ... ,
    userDirectory: ...
}

2. Screen shot by JS code. I think the issues is that there are 2 calls made 1 successful xhr.send and 1 unsuccessful window.open. Cant find any resource online on this. Hope you can help.

Poh_5-1686718413812.pngPoh_6-1686718427816.png

Poh_7-1686718442822.png

 

3. Screen shot by ModHeader

Poh_3-1686718374971.png

Poh_4-1686718387461.png

Thanks!

 

 

 

alex_colombo
Employee
Employee

Point 1 (payload), please verify which configuration you have in the virtual proxy for authentication section, you should have userId (not userID) for JWT attribute for user ID.

Point 2, first call is ok, so you are authenticated. Please check if your code is making that second call (actually I'm seeing three call to the hub, you should have one), becuase that call doesn't have the JWT token attached to the header and then you get 401.

Poh
Contributor II
Contributor II
Author

Hi @alex_colombo,

Point 1: The JWT token i'm using is correct as I am able to login with the modheader extension. I copied the exact same token to test it with my code above.

 

Point 2:

<button onclick="getResponse()">Click Here</button>
<script type = "text/javascript">
    function getResponse() {
    var url = "https://qliksense/jwt/hub";
    var token = "xxx";
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.setRequestHeader('Content-Type','application/json');
    xhr.setRequestHeader('Accept','application/json');
    xhr.setRequestHeader('Authorization',token);
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          console.log(xhr.responseText);
          window.location.href = url;
        }
      } else {
        console.error(xhr.status);
      }
    };
    };

 

This is my code above, I made 2 calls to the website. Any idea why would it be 3? and will you be able to assist? I'm kinda stuck.

 

Thanks!

alex_colombo
Employee
Employee

Why do you make 2 calls? Anyway, as good practice if your intent is to get authenticated, don't fetch the entire hub but fetch a smaller resource, like an image or you can point to one of our very simple api like https://_your_sense_server_/qrs/about (for this you need to pass the xrfkey attribute in the url and in the header as described here).
Another point, I'd change your code from XMLHttpRequest to a simple fetch like this