Simply logout from Keycloak

This blog post is about the logout from Keycloak in a Vue.js application using the keycloak-js SDK/javascript-adapter.

As you maybe know we (Niklas, Harald and I) created an example project called Cloud Native Starter that contains example implementations related to Cloud Native applications with Microservices. I will use one of the example implementations in that blog post.

I structured the blog post in following sections.

  • The simplified solution
  • The basics
  • The example implementation in a Vue.js fronted application

The simplified solution

But, if you only want to know the simplified fact, what you need for the logout? You just need a logut url which contains the redirect url to a page you want to be shown, when a user does a logout from your application. In my example it’s the redirect url to the root URL of the frontend Vue.js web application.

Here you see the structure of the logout url. You need to know the KEYCLOAK_URL, the REALM_NAME and theENCODED_REDIRECT_URI.

http://{KEYCLOAK_URL}/auth/realms/{REALM_NAME}/protocol/openid-connect/logout?redirect_uri={ENCODED_REDIRECT_URI}

The basics

When you logout from Keycloak you should be aware of two topics, these are cookies and tokens.

Cookies

Cookies in the browser which are used by Keycloak, these cookies can be used for an automation of the login to Keycloak. As you see in the image below, cookies can be requiredoptional or disabled for the authentication flows of Keycloak.

In the image below you see the cookies which were created by my local Keycloak instance. You can notice these cookies, aren’t accessible by a script (No(HttpOnly)). So, when we manage the logout correctly Keycloak will put the cookies to the right state and we don’t need to take care about the cookies.

Tokens 

You manage the refresh of a token in your application itself. In our example we implemented the frequently update of the token inside an interval (setInterval).

In the image you see the settings you can use to configure the lifespan of a token in Keycloak.

The example implementation in the Vue.js webapplication

Let me start very simply, before you can logout you need to be logged on.

I will use the relevant parts from the main.js file of our Vue.js frontend application to show how it works. That topic is structured in following sections:

In the main.js file we use the Keycloak SDK/javascript-adapter for the implementation to access Keycloak. The source code for that SDK/javascript-adapter you can find here (/keycloak.d.ts).

The logout is a part of an interval used for the update of the tokens in main.js file, the reason for that is I want to reuse the existing instance of the Keycloak javascript-adapter.

Init

In the following code you see the initOptions, which are the parameters for the instantiation of a Keycloak javascript-adapter instance. In order to create an instance, three pieces of information are required. The Keycloak URL, the realm and the client id.

When the login was successful, we get the tokens from Keycloak, which we will save in an Vue store, with is called store in our code.

You can find in detailed description of the values for the Keycloak init in the SDK/javascript-adapter documentation. (example code in GitHub)

...
let initOptions = {
  url: store.state.endpoints.login , realm: 'quarkus', clientId: 'frontend', onLoad: 'login-required'
}

let keycloak = Keycloak(initOptions);

keycloak.init({ onLoad: initOptions.onLoad }).then((auth) => {
...
  if ((keycloak.token && keycloak.idToken) != '') {
    store.commit("login", payload);
    payload = {
      name: keycloak.tokenParsed.preferred_username
    };
    store.commit("setName", payload);
  }
  else {
    payloadRefreshedTokens = {
      idToken: "",
      accessToken: ""
    }
    store.commit("login", payloadRefreshedTokens);
    store.commit("logout");
  }
...

Token update

In the following interval implementation, you see that the status of the authentication will be frequently verified and when the authentication status in the fronted application is still valid, the token will be updated and saved in the Vue store. (example code in GitHub)

You can find in detailed description for the updateToken() in Keycloak SDK/javascript-adapter documentation.

setInterval(() => {
    keycloak.updateToken().then((refreshed) => {
      if (store.state.user.isAuthenticated != false ) {
        if (refreshed) {       
          let payloadRefreshedTokens = {
            idToken: keycloak.idToken,
            accessToken: keycloak.token
          }
          if ((keycloak.token && keycloak.idToken) != '') {
            store.commit("login", payloadRefreshedTokens);
          }
          else {
            payloadRefreshedTokens = {
              idToken: "",
              accessToken: ""
            }
            store.commit("login", payloadRefreshedTokens);
            store.commit("logout");
          }
        }
      } 
      ...

Logout

Finally, we come to the logout implementation, which is also a part of the interval implementation (so the logout takes bit) to take the advantage of the existing Keycloak javascript-adapter instance in the example.

The documentation of the logout() for the Keycloak SDK/javascript-adapter isn’t as detailed as for the init and token update.

I figured out that we need to create a logout URL as you can verify in the documentation for a logout. The given logout documentation of the javascript-adapter doesn’t contain the needed format for the parameter options. But finally, I found the options in the source code of the javascript-adapter in the keycloak.d.ts file.

The Keycloak logout URL must contain the valid redirect URL, in this example the URL is http://localhost:8080/, the same URL as for the redirect of the login to the Vue.js frontend application.

My finding resulted in the following simple definition:

logoutOptions = { redirectUri : "http://localhost:8080/" }

When you know that the logout is very simple as you see in the following source code. (example code in GitHub)

...
    var logoutOptions = { redirectUri : urls.cns };

    keycloak.logout(logoutOptions).then((success) => {
            console.log("--> log: logout success ", success );
    }).catch((error) => {
            console.log("--> log: logout error ", error );
    });
    store.commit("logout");
...

The gif below shows the working logout.

Summary

At the end the implementation of the logout is very simple, but it wasn’t so easy to find the parameter for the logout of the javascript-adapter. It’s awesome that you can dig into the source code, because Keycloak is open-source, when you miss a tiny little detail in the documentation ;-).



I hope this was useful for you and let’s see what’s next?

Greetings,

Thomas

#vue, #keycloak, #logout, #javascript, #cloudnativestarter

3 thoughts on “Simply logout from Keycloak

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.