keycloak js automatic token refesh

11,851

Solution 1

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(() => {...});
}

Solution 2

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

Share:
11,851
boycod3
Author by

boycod3

??????????????

Updated on June 17, 2022

Comments

  • boycod3
    boycod3 almost 2 years

    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>';
                    });
        }
    
  • Yalamber
    Yalamber over 4 years
    does token get refreshed even after existing token is expired?
  • Logus Graphics
    Logus Graphics over 3 years
    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.
  • Lisa
    Lisa about 2 years
    @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 ?
  • Fabian
    Fabian about 2 years
    @Lisa I usually work with React but I found this in the readme of keycloak-angular: github.com/mauriciovigolo/keycloak-angular#keycloak-js-event‌​s and it looks like it will work similar for you :)