Keycloak plugin for Vue 3 with Composition API
npm install @josempgon/vue-keycloak![]() | ➕ |
A small Vue wrapper library for the Keycloak JavaScript adapter.
> This library is made for Vue 3 with the Composition API.
Using npm:
``bash`
npm install @josempgon/vue-keycloak
Using yarn:
`bash`
yarn add @josempgon/vue-keycloak keycloak-js
Using pnpm:
`bash`
pnpm add @josempgon/vue-keycloak keycloak-js
Import the library into your Vue app entry point.
`typescript`
import { vueKeycloak } from '@josempgon/vue-keycloak'
Apply the library to the Vue app instance.
`typescript
const app = createApp(App)
app.use(vueKeycloak, {
config: {
url: 'http://keycloak-server',
realm: 'my-realm',
clientId: 'my-app',
}
})
`
| Object | Type | Required | Description |
| ----------- | --------------------------------------------- | -------- | ---------------------------------------- |
| config | [KeycloakConfig][Config] | Yes | Keycloak configuration. |KeycloakInitOptions
| initOptions | [][InitOptions] | No | Keycloak init options. |
#### initOptions Default Value
`typescript`
{
flow: 'standard',
checkLoginIframe: false,
onLoad: 'login-required',
}
#### Dynamic Keycloak Configuration
Use the example below to generate a dynamic Keycloak configuration. In that example the Keycloak adapter is initialized in silent check-sso mode. Be aware that this mode could have limited functionality with recent browser versions (check Modern Browsers with Tracking Protection for additional info).
`typescript${location.origin}/silent-check-sso.html
app.use(vueKeycloak, async () => {
const url = await getAuthBaseUrl()
const silentCheckSsoRedirectUri = `
return {
config: {
url,
realm: 'my-realm',
clientId: 'my-app',
},
initOptions: {
onLoad: 'check-sso',
silentCheckSsoRedirectUri,
},
}
})
package and need to initialize the router only after the authentication process is completed, you should initialize your app in the following way:router/index.js
`typescript
import { createRouter, createWebHistory } from 'vue-router'const routes = [ / Your routes / ]
const initRouter = () => {
const history = createWebHistory(import.meta.env.BASE_URL)
return createRouter({ history, routes })
}
export { initRouter }
`main.js
`javascript
import { createApp } from 'vue'
import { vueKeycloak } from '@josempgon/vue-keycloak'
import vueKeycloakConfig from './config/vueKeycloak.js'
import App from './App.vue'
import { initRouter } from './router'const app = createApp(App)
await vueKeycloak.install(app, vueKeycloakConfig)
app.use(initRouter())
app.mount('#app')
`If you are building for a browser that does not support Top-level await, you should wrap the Vue plugin and router initialization in an async IIFE:
`javascript
(async () => {
await vueKeycloak.install(app, vueKeycloakConfig); app.use(initRouter());
app.mount('#app');
})();
`Use Token
A helper function is exported to manage the access token.
$3
| Function | Type | Description |
| ---------------- | ------------------------------------------------------ | ---------------------------------------------------------------------- |
| getToken |
(minValidity?: number) => Promise\
| Returns a promise that resolves with the current access token. |The token will be refreshed if expires within
minValidity seconds. The minValidity parameter is optional and defaults to 10. If -1 is passed as minValidity, the token will be forcibly refreshed.A typical usage for this function is to be called before every API call, using a request interceptor in your HTTP client library.
`typescript
import axios from 'axios'
import { getToken } from '@josempgon/vue-keycloak'// Create an instance of axios with the base URL read from the environment
const baseURL = import.meta.env.VITE_API_URL
const instance = axios.create({ baseURL })
// Request interceptor for API calls
instance.interceptors.request.use(
async config => {
const token = await getToken()
config.headers['Authorization'] =
Bearer ${token}
return config
},
error => {
Promise.reject(error)
},
)
`Composition API
`vue
Loading...
Welcome to Your Keycloak Secured Vue.js App
User: {{ username }}
User ID: {{ userId }}
Authentication Error
{{ error }}
`$3
The
useKeycloak function exposes the following data.#### Reactive State
| State | Type | Description |
| --------------- | ------------------------------------------------------ | ------------------------------------------------------------------- |
| keycloak |
ShallowRef<[Keycloak][Instance]> | Instance of the keycloak-js adapter. |
| isAuthenticated | Ref | If true the user is authenticated. |
| isPending | Ref | If true the authentication request is still pending. |
| hasFailed | Ref | If true an error ocurred on initialization or Keycloak request. |
| error | Ref | Info on error that ocurred (null if no error) |
| token | Ref | Raw value of the access token. |
| decodedToken | Ref<[KeycloakTokenParsed][TokenParsed]> | Decoded value of the access token. |
| username | Ref | Username. Extracted from decodedToken['preferred_username']. |
| userId | Ref | User identifier. Extracted from decodedToken['sub']. |
| roles | Ref | List of the user's roles. |
| resourceRoles | Ref | List of the user's roles in specific resources. |#### Functions
| Function | Type | Description |
| ---------------- | --------------------------------------------------------- | ----------------------------------------------------------------- |
| hasRoles |
(roles: string[]) => boolean
| Returns true if the user has all the given roles. |
| hasResourceRoles | (roles: string[], resource: string) => boolean
| Returns true` if the user has all the given roles in a resource. |This project is licensed under the Apache License 2.0.
Originally developed by Gery Hirschfeld (2021).
Maintained and extended by José Miguel Gonçalves (2021-present).
[Config]: https://github.com/keycloak/keycloak-js/blob/26.2.1/lib/keycloak.d.ts#L27-L40
[InitOptions]: https://github.com/keycloak/keycloak-js/blob/26.2.1/lib/keycloak.d.ts#L82-L231
[TokenParsed]: https://github.com/keycloak/keycloak-js/blob/26.2.1/lib/keycloak.d.ts#L360-L375
[Instance]: https://github.com/keycloak/keycloak-js/blob/26.2.1/lib/keycloak.d.ts#L399-L685