for keycloak + angular + cordova app, logout only seems to work if done within a 10-15 seconds of login

Viewed 1758

for my application (angular app, uses Keycloak for auth and Cordova for making it into ios and android apps) the behavior of logout is weird observation with logout

  1. login to the application and keep the app ideal for a minute
  2. press logout the app shows a web page moment and then redirects to the default route (as if there is no logout was requested
  3. if you keep the app ideal for a minute, then the same thing will repeat.
  4. if logout is pressed within 10-15 seconds of login or after step 2 the app will log out successfully.

config at Keycloak server

enter image description here

I am using the following config for Keycloak init enter image description here

and this is the code in the logout enter image description here

for the web app (desktop and iPad) things are working as expected.

I have tried to redirect the app to the logout URL provided in Keycloak docs#logout, however, did not work as expected.

expected outcome: once logout is clicked the app should logout and the login page should be visible.

Has anyone encountered this sort of issue? if any more details are required to debug this issue please let me know.

Versions used:

  • Keycloak: 10.0.0
  • Angular: ~10.1.1
  • Cordova: 10.0.0
  • cordova-android:^9.0.0
  • cordova-ios: ^6.1.1
1 Answers

Unsure if your problem is related. But for my scenario I was having this problem with the logout implementation on IOS. Keycloak uses cordovas inappbrowser, which waits for the loadstart event, checks that URL is equal to localhost, and then closes the browser. On close, the exit event should be fired, which is then intercepted by the keycloak-js adapter, which then returns from the logout function. See this code:

logout: function(options) {

var promise = createPromise();

var logoutUrl = kc.createLogoutUrl(options);
var ref = cordovaOpenWindowWrapper(logoutUrl, '_blank', 'location=no,hidden=yes');

var error;

ref.addEventListener('loadstart', function (event) {
    if (event.url.indexOf('http://localhost') == 0) {
        ref.close();
    }
});

ref.addEventListener('loaderror', function (event) {
    if (event.url.indexOf('http://localhost') == 0) {
        ref.close();
    } else {
        error = true;
        ref.close();
    }
});

ref.addEventListener('exit', function (event) {
    if (error) {
        promise.setError();
    } else {
        kc.clearToken();
        promise.setSuccess();
    }
});

return promise.promise;
},

https://github.com/keycloak/keycloak/blob/0362d3a4304eccc66a5e4d018b39689883f126a3/adapters/oidc/js/src/main/resources/keycloak.js

Ther is a bug in inappbrowser which means this exit even never fires. See https://github.com/apache/cordova-plugin-inappbrowser/issues/649.

This means the promise.setError or promise.setSuccess never fires.

As a workaround, you could modify the keycloak-js library as so:

ref.addEventListener('loaderror', function (event) {
 if (event.url.indexOf('http://localhost') == 0) {
     kc.clearToken();
     promise.setSuccess();
     ref.close();
 } else {
     error = true;
     promise.setError();
     ref.close();
 }
});
Related