Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keycloak js not executing THEN after init

I am trying to integrate Keycloak login into my React app and I'm trying to get the JWT from keycloak. Here is the code:

  const [keycloakState, setKeycloakState] = useState<any>();

  const login = () => {
    const keycloak = Keycloak("/keycloak.json");

    keycloak.init({onLoad: 'login-required'}).then(authenticated => {
      console.log('kk', keycloak)
      console.log('at', authenticated)
      setKeycloakState({ keycloak: keycloak, authenticated: authenticated });
    }).catch(err => {
      alert(err);
    });

    console.log('log after')
  }

The login function is triggered when a button is clicked. It redirects properly to keycloak, I can log in and I am properly redirected to the app. The problem is that after the redirect back to the app with proper login the code in the then part of the chain is not executed, and even the 'log after' does not appear in the logs. The catch error part works fine.

Why might this be happening? I have keycloak-js added to my project.

like image 784
Matt Avatar asked Oct 11 '25 15:10

Matt


2 Answers

I think the reason your fulfilled callback is not executed is the way your app interacts with Keycloak. You initialize the Keycloak-Adapter with onLoad: 'login-required' which will redirect the user to Keycloak - which means the Javascript execution is interrupted at this point. Keycloak will redirect the user back to your app and since you wrapped the Keycloak-Adapter in a function which is only executed when a button is clicked, the promise callback is not executed.

Simple example:

// do this on page load
keycloak.init({onLoad: 'login-required'}).then((authenticated) => {
  console.log('authenticated', authenticated)
})

You will not see a "authenticated", false in your console when you open up your app. If the user is not authenticated, he will be redirected (so no chance to execute that callback). If he then comes back and is authenticated, the callback will be executed and authenticated should be true.

If you want the user to click a button, a setup like this should work:

// do this somewhere early in your App or main.js and in a way that this code is executed on page load
const keycloak = new Keycloak(configuration);

keycloak.init({onLoad: 'check-sso'}).then((authenticated) => {
    if (authenticated) {
        // do what needs to be done if sign in was successful, for example store an access token
    } else {
        // handle failed authentication
    }
}).catch(err => {
  alert(err);
});

const login = () => { // this could be an on-click event handler
    keycloak.login();
};

check-sso won't redirect the user to Keycloak if unauthenticated, so the user can trigger the login when needed.

Keep in mind that your JavaScript code will run twice and you have to cover both cases, first the user is not authenticated and needs to be redirected to Keycloak and a second time once the user comes back from Keycloak (then we should get the information that the user is authenticated in .then().

like image 75
justarustyspoon Avatar answered Oct 14 '25 06:10

justarustyspoon


I used to face this problem before. The way that I passed is separating the "init" function and then invoke it later. Here is my example on jsFiddle: 'https://jsfiddle.net/gzq6j3yu/1/'

like image 28
K9.dev Avatar answered Oct 14 '25 05:10

K9.dev