vue-keycloak-js icon indicating copy to clipboard operation
vue-keycloak-js copied to clipboard

how to define $keycloak on vue 3 using JavaScript

Open rkrajukhunt opened this issue 2 years ago • 11 comments

how I can convert this into js in Vue 3

// Allow usage of this.$keycloak in components declare module '@vue/runtime-core' { interface ComponentCustomProperties { $keycloak: VueKeycloakInstance } }

rkrajukhunt avatar Jun 06 '22 18:06 rkrajukhunt

Hello @rkrajukhunt did you get a solution to this?

DavidzMwangi avatar Jun 21 '22 07:06 DavidzMwangi

I haven't really tested this. But i would think that you wouldn't really have to convert it to javascript. It is to allow typescript to know that there is something on the Vue component called $keycloak and what type it has. Javascript dont need to know that to be able to use it.

baltom avatar Jun 22 '22 05:06 baltom

@baltom did this lib handle redirect to mobile app too

i am using a keycloak with quasar, i build app using capacitor like a ionic

redirection is working fine with keycloak to web app, i am stuck in redirect to mobile app

can you help me out

rkrajukhunt avatar Jun 30 '22 07:06 rkrajukhunt

@rkrajukhunt Have never tried before i'm afraid. Maybe someone else has any experience

baltom avatar Jul 04 '22 13:07 baltom

I have tried and failed.

    if (Platform.is.cordova || Platform.is.capacitor) {
      initOptions = {
        ...initOptions,
        adapter: 'cordova',
        // redirectUri: 'https://myapp.local/',
//        redirectUri: 'android-app://local.myapp/https/local.myapp/login'
        redirectUri: 'android-app://'
      }
    }

It's just not working. But this issue isn't about this, right?

dl74i avatar Jul 07 '22 15:07 dl74i

Have the same issue! Cannot get access to the instance of $keycloak. All examples are using Typescript but I want a plain javascript one! :(

stratosgear avatar Jul 17 '22 13:07 stratosgear

Have the same issue! Cannot get access to the instance of $keycloak. All examples are using Typescript but I want a plain javascript one! :(

In templates you should be able to reference $keycloak without having to do anything (other than installing the plugin of course) however if using it from script tag its not located on the Vue object as in vue2. It's on globalProperties (https://github.com/dsb-norge/vue-keycloak-js/blob/main/src/index.ts#L102) which is on the app context. or you could inject it into your script https://vuejs.org/guide/components/provide-inject.html

baltom avatar Jul 21 '22 07:07 baltom

Thanks @baltom for the direct pointers to the code where things are implemented.

Unfortunately I am still not sure how to properly access the $keycloak var. In my case (using latest Quasar with latest vue) the $keycloak var does not resolve from either the template section neither the script section of my .vue files.

Only "hack" that I was able to come with (that I am sure that any day now will reveal some limitation) was to do define a custom kc var likewise (marked as HACK HERE below):

import VueKeyCloak from "@dsb-norge/vue-keycloak-js";
import { boot } from "quasar/wrappers";
import { api } from "boot/axios";

// HACK HERE
var kc = null;

export default boot(async ({ app, router, store }) => {
  async function tokenInterceptor() {
    api.interceptors.request.use(
      (config) => {
        config.headers.Authorization = `Bearer ${app.config.globalProperties.$keycloak.token}`;
        return config;
      },
      (error) => {
        return Promise.reject(error);
      }
    );
  }

  return new Promise((resolve) => {
    app.use(VueKeyCloak, {
      init: {
        onLoad: "login-required",
        flow: "standard",
        pkceMethod: "S256",
        silentCheckSsoRedirectUri:
          window.location.origin + "/silent-check-sso.html",
        checkLoginIframe: false, // otherwise it would reload the window every so seconds
      },
      config: {
        url: process.env.KEYCLOAK_HOST,
        realm: process.env.KEYCLOAK_REALM,
        clientId: process.env.KEYCLOAK_CLIENT_ID,
      },
      // initOptions: {
      //   // pkceMethod: 'S256',
      //   // must match to the configured value in keycloak
      //   // redirectUri: 'http://localhost:4200/your_url',
      //   // this will solved the error
      //   checkLoginIframe: false,
      // },
      onReady: (keycloak) => {
        tokenInterceptor();
        resolve();
        // HACK HERE
        kc = keycloak;
      },
    });
  });
});

// declare module "@vue/runtime-core" {
//   interface ComponentCustomProperties {
//     $keycloak: VueKeycloakInstance;
//   }
// }

// HACK HERE
export { kc };

then in my .vue files:

<script setup>
import { kc } from "boot/keycloak";
...
...

which allows me to use kc from both the template and script section.

If you could be a little more detailed and give me the reference to the $keycloak when you mention:

It's on globalProperties (https://github.com/dsb-norge/vue-keycloak-js/blob/main/src/index.ts#L102) which is on the app context.

that would be great! You mean access it like: app.config.globalProperties.$keycloak ? Where would I get access to app from a random .vue file?

Thanks once more! I would really like to remove my "hack" from above! (Here is a pre-emptive :beer:, btw)

stratosgear avatar Jul 21 '22 11:07 stratosgear

To @stratosgear :

This is what I did:

In my boot file (Quasar):

onReady: (keycloak) => {
        tokenInterceptor()
        app.provide('keycloak', keycloak)
        resolve()
      }

In my vue components (setup function):

const kc = inject('keycloak')

You'll need to import inject from Vue.

It works, but what I do not understand is that it's already in the vue-keycloak-js source code. However injecting it in Vue component is not working, don't know why.

https://github.com/dsb-norge/vue-keycloak-js/blob/main/src/index.ts#L104

jra11 avatar Oct 29 '22 17:10 jra11

@jra11 according to https://vuejs.org/guide/components/provide-inject.html#working-with-symbol-keys one would have to import the symbol, but where is that symbol located? https://github.com/dsb-norge/vue-keycloak-js/blob/main/src/index.ts#L12 says it's not exported, it's just const KeycloakSymbol

idc77 avatar Jan 31 '23 14:01 idc77

see #161

import {defineComponent,inject} from 'vue'
import VueKeyCloak from '@dsb-norge/vue-keycloak-js'

export default defineComponent({
  name: 'MainLayout',
  setup() {
    const symbol = VueKeyCloak.KeycloakSymbol
    const kc = inject(symbol)
    console.log(kc.tokenParsed)
  }
})

even if the IDE complains that

Argument type symbol is not assignable to parameter type InjectionKey<unknown> | string
Type symbol is not assignable to type string
 Type symbol is not assignable to type InjectionKey<unknown> 

idc77 avatar Apr 06 '23 22:04 idc77