Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keycloak object property "authenticated" returns false when should be true

So, I am working on a react-redux app which requires some users to authenticate, which I use keycloak for.

Basically there is a homepage thats public/not secured at:
- localhost:3000/

Now when the user clicks a link to go to the welcome page, the keycloak login page should popup and ask for authentication details, which I already managed to do:
- localhost:3000/welcome -> localhost:8080/auth

As stated above, the login page already shows up and correctly authenticates registered users. However, once successfully logged in, I am being redirected to localhost:3000/welcome (which is good), but without any content (which is not good).

So i went on to log the status of keycloak.authenticated to the console. Before calling "keycloak.init" it is undefined (which is fine), after successful authenticated it is false (:o?!?!).

Weird.

So it seems that i must manually change the status of keycloak.authenticated.

2 Questions: - how do i change keycloak.authenticated in the face of reduxish stateless components w/o constructors etc. - am i even right about my question?

Some formalities:

keycloak.js Code of the higher order component which the Welcome page is wrapped with:

import React from 'react';

const { Consumer, Provider } = React.createContext();
export const KeycloakProvider = Provider;
const withKeycloak = component =>
  function WithKeycloak(props) {
    return React.createElement(Consumer, null, keycloak => {
      console.log('before: ', keycloak.authenticated); -> undefined
      if (keycloak.authenticated) {
        return React.createElement(component, { ...props, keycloak }, null);
      }
      console.log('before init: ', keycloak.authenticated); // -> undefined
      keycloak.init({ onLoad: 'login-required' });
      console.log('after: ', keycloak.authenticated); // -> false!!
      return null;
    });
  };

export default withKeycloak;

main.jsx Code of main.jsx where keycloak is being defined:

/** @format */

import lots of stuff....;
import { KeycloakProvider } from './keycloak/provider';
import Keycloak from 'keycloak-js';

const store = ...

const keycloak = Keycloak({
  url: 'http://localhost:8080/auth',
  realm: 'Test-Jannis',
  clientId: 'test-bayron'
});

const Main = () => (
  <Provider store={store}>
    <BrowserRouter>
        <KeycloakProvider value={keycloak}>
          <Route exact path="/" component={Home} />
          <Route exact path="/welcome" component={WelcomePage} />
        </KeycloakProvider>
    </BrowserRouter>
  </Provider>
);

export default Main;

My best guess would be to do something like this in under keycloak.init in keycloak.js:

keycloak.init({ onLoad: 'login-required' });
   .then(authenticated => (keycloak.authenticated = authenticated));

But...that doesn't change keycloak.authenticated to be false.

Please help :)

UPDATE

Using the following code for keycloak.js:

const withKeycloak = component =>
  function WithKeycloak(props) {
    return React.createElement(Consumer, null, keycloak => {
      console.log('before: ', keycloak.authenticated);
      keycloak.init({ onLoad: 'login-required'}).success(function() {
        if ( keycloak.authenticated ) {
          console.log("return page: ", keycloak.authenticated);
          console.log(component);
          console.log(React.createElement(component, { ...props, keycloak }, null));
          return React.createElement(component, { ...props, keycloak }, null);
        }
        console.log("return null: ", keycloak.authenticated);
        return null;
      });
    });
  };

Now outputs keycloak.authenticated === true! However, the redirected localhost:3000/welcome still doesn't display any of the html the welcome component is supposed to show.

like image 970
Jannis Busch Avatar asked Sep 01 '25 10:09

Jannis Busch


1 Answers

Following KeyCloak JS adapter documentation:

By default, the JavaScript adapter creates a hidden iframe that is used to detect if a Single-Sign Out has occurred. This does not require any network traffic, instead the status is retrieved by looking at a special status cookie. This feature can be disabled by setting checkLoginIframe: false in the options passed to the init method.

You need to put your keycloak initialization code as:

keycloak.init({checkLoginIframe: false}).success((authenticated) => {
  // Some stuff
})
like image 81
Tarik Curto Avatar answered Sep 04 '25 00:09

Tarik Curto