7

I have a piece of code working with keycloak and JS. The code working perfectly except refresh token method have to call externally when the token is expired. How can I refresh token automatically when expired.

 var keycloak = Keycloak('keycloak.json');

 keycloak.init({ onLoad: 'login-required' })
        .success(reloadData)
        .error(function(errorData) {
            document.getElementById('customers').innerHTML = '<b>Failed to load data. Error: ' + JSON.stringify(errorData) + '</b>';
    });

 var loadData = function () {
        document.getElementById('subject').innerHTML = keycloak.subject;
        if (keycloak.idToken) {
            document.getElementById('profileType').innerHTML = 'IDToken';
            document.getElementById('username').innerHTML = keycloak.idTokenParsed.preferred_username;
            document.getElementById('email').innerHTML = keycloak.idTokenParsed.email;
            document.getElementById('name').innerHTML = keycloak.idTokenParsed.name;
            document.getElementById('givenName').innerHTML = keycloak.idTokenParsed.given_name;
            document.getElementById('familyName').innerHTML = keycloak.idTokenParsed.family_name;
        } else {
            keycloak.loadUserProfile(function() {
                document.getElementById('profileType').innerHTML = 'Account Service';
                document.getElementById('username').innerHTML = keycloak.profile.username;
                document.getElementById('email').innerHTML = keycloak.profile.email;
                document.getElementById('name').innerHTML = keycloak.profile.firstName + ' ' + keycloak.profile.lastName;
                document.getElementById('givenName').innerHTML = keycloak.profile.firstName;
                document.getElementById('familyName').innerHTML = keycloak.profile.lastName;
            }, function() {
                document.getElementById('profileType').innerHTML = 'Failed to retrieve user details. Please enable claims or account role';
            });
        }

        var url = '/database/customers';
        var 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) {
                    var users = JSON.parse(req.responseText);
                    var html = '';
                    for (var i = 0; i < users.length; i++) {
                        html += '<p>' + users[i] + '</p>';
                    }
                    document.getElementById('customers').innerHTML = html;
                    console.log('finished loading data');
                }
            }
        }
        req.send();
    };
    var loadFailure = function () {
        document.getElementById('customers').innerHTML = '<b>Failed to load data.  Check console log</b>';
    };
    var reloadData = function () {
        keycloak.updateToken(10)
                .success(loadData)
                .error(function() {
                    document.getElementById('customers').innerHTML = '<b>Failed to load data.  User is logged out.</b>';
                });
    }
boycod3
  • 5,033
  • 11
  • 58
  • 87

2 Answers2

18

I know it's very late, but this answer is just for a future reference.

Don't know if it's just new and this handler was not implemented in 2017 but I use keycloak.onTokenExpired to do this.

Just an example:

keycloak.onTokenExpired = () => {
    console.log('token expired', keycloak.token);
    keycloak.updateToken(30).success(() => {
        console.log('successfully get a new token', keycloak.token);
        ...
    }).error(() => {...});
}
Fabian
  • 3,139
  • 2
  • 23
  • 49
  • does token get refreshed even after existing token is expired? – Yalamber Sep 18 '19 at 17:59
  • 1
    If the handler is based on a timeout and the min validity is greater than the current timestamp, then the refresh token should be good for generating a new valid access token. – Logus Graphics Aug 17 '20 at 15:59
  • @Fabian i am using KeycloakService from 'keycloak-angular'; a JS adapter , but i do not find this 'onTokenExpired' with this adapter, there is some thing called 'isTokenExpired()' which is not working whenever the token got expired , Do you have an idea on how to use this ? – Lisa Feb 09 '22 at 07:23
  • 1
    @Lisa I usually work with React but I found this in the readme of keycloak-angular: https://github.com/mauriciovigolo/keycloak-angular#keycloak-js-events and it looks like it will work similar for you :) – Fabian Apr 10 '22 at 19:52
4

This is only works in Standard flow or Hybrid. There is no possibility to refresh token during implicit flow.

Token (Access Token Lifespan) will be refreshed as long as refreshed token (SSO Session Idle) has not expired. This will work for the duration of SSO Session Max.

Example Token (Access Token Lifespan) will expire in 2 min you can refresh it during 5 min with refreshed token (SSO Session Idle). And it will work maximum during 10 hours SSO Session Max enter image description here

Access Token Lifespan could be overwritten in Clients (see right nav) Settings tab scroll down to Advanced Settings

Alex Gontcharov
  • 111
  • 2
  • 8