Skip to main content
Skip table of contents

Protecting your API and hosted web content

Hosting content through the Flow App should include the following procedures to implement security measures in handling HTTP requests to restrict access to authorized users. The first will implement check-in webpages hosted through Node-RED by adding a Keycloak library to check for active sessions. The second will add the necessity to add a Bearer Token to every other HTTP request with the Node-RED flow acting like an API.

HTML pages

HTML documents hosted through a Node-RED Flow App can be secured by adding a Keycloak check to the JavaScript part of the HTML page. Keycloak provides a JS library to connect to a Keycloak client and check the user session. If no user is logged in, Keycloak will redirect to the qibb login page. If the session expires, Keycloak will automatically redirect to the login as well.

https://www.keycloak.org/docs/latest/securing_apps/#_javascript_adapter

The keycloak.js file necessary is hosted on every Keycloak instance. It will be in the directory /auth/js/keycloak.js of the Keycloak instance. The script has to be included as a source in the HTML file. The address /js/keycloak.js is set for the HTTP node hosting the file. More information on hosting HTML pages or static files through Node-RED is in Serving web content .

HTML
<script src="https://auth.address.com/auth/js/keycloak.js"></script>

To integrate the Keycloak library, two lines are necessary to add as Javascript code.

JS
const keycloak = Keycloak({
        realm: '<keycloak-realm>',
        url: '<https://auth.address.com/auth>',
        clientId: '<client-id>'
    });
  
keycloak.init({ onLoad: 'login-required' });

To connect the clientside Keycloak, it needs some information about the Keycloak server it is supposed to connect to. The config will provide the necessary information about the Keycloak address, realm, and a client from which the user has to request a login. The Keycloak client has to be Access Type: public. It also needs Valid redirect URIs and WebOrigins. To add any address, a * can be used for both settings. Since this client has to be set to public, a dedicated client just for handling UI requests in Flow Apps is advised.

The keycloak.init will initialize Keycloak on that webpage with the added option login-required as shown below. This setup will force a redirect to the login page if there is no valid Keycloak session.

If Keycloak in the client script has a valid session, Keycloak can use a Bearer token to make further HTTP requests from the client page. If keycloak is the object created with the Keycloak config, keycloak.token stores the current token. This token will not be renewed automatically. To request a new token, the function keycloak.updateToken(30) can be used. The number indicated the minimum expiration time in seconds.

The following example requests a new token to make an XMLHttpRequest.

JS
keycloak.updateToken(30).then(function() {
    let url = `https://some-address.com`;

    let req = new XMLHttpRequest();
    req.open('GET', url, true);
    req.setRequestHeader('Accept', 'application/json');
    req.setRequestHeader('Authorization', 'Bearer ' + keycloak.token);

    req.onreadystatechange = function () {
        if (req.readyState == 4) {
            if (req.status == 200) {
                evaluateResponse(req.response);
            } else {
                console.error(req.response);
            }
        }
    }
    req.send();
}).catch(function() {
    console.error('Failed to refresh token');
});

API endpoints

An API endpoint in the Flow App can be secured by implementing a Bearer Token verification. The subflow below (auth-guard.json) can be used to handle the token verification.

auth-guard.json

It will decode the token and compare its Key ID (KID) with a stored KID. If no KID is stored, or the value is different, a new Public Key will be requested. A Keycloak Public Key can be used to verify the signature of the token. If it is verified, the token and a decoded version of it will be exported from the Auth Guard Subflow. The decoded token can then be used for further analysis.

Further analysis might include checking audience members or client roles in the token to decide on a strategy of granting user-specific access or denying it.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.