keycloaknuxt3.js

Accesssing Keycloak plugin property does not provide the right value


I'm trying to authenticate using Keycloak JS in a nuxt project, so I defined a plugin like so :

// plugins/keycloakjs.client.ts

import Keycloak, { KeycloakConfig } from "keycloak-js";

export default defineNuxtPlugin(_nuxtApp => {
        const runtimeConfig = useRuntimeConfig();
        try {
            const keycloakConfig : KeycloakConfig = {
                url: runtimeConfig.public.keycloakUrl,
                realm: runtimeConfig.public.keycloakRealm,
                clientId: runtimeConfig.public.keycloakClientId,
            }

            const keycloak = new Keycloak(keycloakConfig);
            keycloak.init({
                onLoad: "check-sso"
            });
            return {
                provide: {
                    keycloak,
                },
            };
        } catch (e) {
            console.error(e)
            throw createError({ statusCode: 401, message: "Keycloak error" });
        }
});

I try to use it in a navbar component that is used directly in the app.vue file like so :

// ~/app.vue

<script setup lang="ts">
import AppNavbar from "~/components/AppNavbar.vue";
</script>

<template>
  <div class="h-screen">
    <app-navbar />
    <NuxtPage />
  </div>
</template>

And finally the component :

// components/AppNavbar.vue

<script setup lang="ts">
import Keycloak from "keycloak-js";
import { onMounted } from "vue";

const {$keycloak} = useNuxtApp()

const state = reactive({
  authenticated: false,
  token: null
})

onMounted( () => {
  console.log('Keycloak', $keycloak)
  console.log('Keycloak authenticated', $keycloak.authenticated)

  if ($keycloak.authenticated) {
    state.authenticated = true
    state.token = $keycloak?.token
  }
  console.log('state', state)
})

</script>

<template>
  <div class="bg-yellow p-4 flex items-center gap-3">
    <button class="bg-purple p-2 rounded" @click="$keycloak.logout" v-if="state.authenticated">Logout</button>
    <button class="bg-purple p-2 rounded" @click="$keycloak.login" v-else>Login</button>
    <div class="bg-purple p-2 rounded w-1/2">{{ state.token }}</div>
  </div>
</template>

But when I load the app the authenticated local state remains to false. When logging the plugin value I get authenticated value to true but when calling the property it always return false. What am I missing please ?

enter image description here


Solution

  • I forgot to deal with the init promise. Here is the corrected version :

    // plugins/keycloakjs.client.ts
    
    import Keycloak, { KeycloakConfig } from "keycloak-js";
    
    export default defineNuxtPlugin(async _nuxtApp => {
            const runtimeConfig = useRuntimeConfig();
            try {
                const keycloakConfig : KeycloakConfig = {
                    url: runtimeConfig.public.keycloakUrl,
                    realm: runtimeConfig.public.keycloakRealm,
                    clientId: runtimeConfig.public.keycloakClientId,
                }
    
                const keycloak = new Keycloak(keycloakConfig);
                await keycloak.init({
                    onLoad: "check-sso"
                });
                return {
                    provide: {
                        keycloak,
                    },
                };
            } catch (e) {
                console.error(e)
                throw createError({ statusCode: 401, message: "Keycloak error" });
            }
    });