javascript - Keycloak js not executing THEN after init - Stack Overflow

admin2025-04-08  0

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.

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.

Share Improve this question asked Mar 25, 2021 at 20:23 MattMatt 3741 gold badge5 silver badges15 bronze badges 3
  • did you ever find a solution to this? – Cory Kleiser Commented Aug 25, 2021 at 15:05
  • @CoryKleiser did you got solution for this ? – SOURAV KUMAR Commented Sep 17, 2022 at 13:19
  • @SOURAVKUMAR I posted the solution I came up with below and added a helper note to access the token anytime. – Cory Kleiser Commented Sep 20, 2022 at 18:38
Add a ment  | 

3 Answers 3

Reset to default 4

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 es 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 es back from Keycloak (then we should get the information that the user is authenticated in .then().

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/gzq6j3yu/1/'

Our solution was to use the functions onAuthSuccess and onAuthError avaliable on the KeycloakInstance keycloak-js provides. (The documentation around this is a little shaky but you can find them if you check out the source code.) As the names imply these functions get called when an auth attempt is successful or unsuccessful, respectively.

note: in the following snippets this._instance replaces OP's keycloak constant.

Basic code snippet:

import Keycloak from 'keycloak-js';

...

// pulled from a class's init function from a custom Keycloak helper class so won't translate one for one but you get the point.

this._instance = Keycloak(configObject);

this._instance.onAuthSuccess = () => { 
  // code to execute on auth success
};

this._instance.onAuthError = () => {
  // code to execute on auth error
};

this._instance.init(initOptions)

...

We also had a getter to get the token on the KeycloakInstance (or empty string) on the same class. This is an easy way to refer to the token in your code to check if it actually exists, etc. Here's what that'd look like inside the class.

  get token() {
    return this._instance ? this._instance.token : '';
  }

Hope this can help out some folks.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744124351a232394.html

最新回复(0)