@josempgon/vue-keycloak
v3.1.0
Published
Keycloak plugin for Vue 3 with Composition API
Downloads
3,706
Maintainers
Readme
vue-keycloak
A small Vue wrapper library for the Keycloak JavaScript adapter.
This library is made for Vue 3 with the Composition API.
Instalation
Install the library with npm.
npm install @josempgon/vue-keycloak
Use Plugin
Import the library into your Vue app entry point.
import { vueKeycloak } from '@josempgon/vue-keycloak'
Apply the library to the Vue app instance.
const app = createApp(App)
app.use(vueKeycloak, {
config: {
url: 'http://keycloak-server/auth',
realm: 'my-realm',
clientId: 'my-app',
}
})
Configuration
| Object | Type | Required | Description |
| ----------- | --------------------------------------------- | -------- | ---------------------------------------- |
| config | KeycloakConfig
| Yes | Keycloak configuration. |
| initOptions | KeycloakInitOptions
| No | Keycloak init options. |
initOptions
Default Value
{
flow: 'standard',
checkLoginIframe: false,
onLoad: 'login-required',
}
Dynamic Keycloak Configuration
Use the example below to generate dynamic Keycloak configuration.
app.use(vueKeycloak, async () => {
const authBaseUrl = await getAuthBaseUrl()
return {
config: {
url: `${authBaseUrl}/auth`,
realm: 'my-realm',
clientId: 'my-app',
},
initOptions: {
onLoad: 'check-sso',
silentCheckSsoRedirectUri: `${window.location.origin}/assets/silent-check-sso.html`,
},
}
})
Use with vue-router
If you need to wait for authentication to complete before proceeding with your Vue app setup, for instance, because you are using the vue-router
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.ts
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.ts
import { createApp } from 'vue'
import { vueKeycloak } from '@josempgon/vue-keycloak'
import App from './App.vue'
import { initRouter } from './router'
const app = createApp(App)
await vueKeycloak.install(app, {
config: {
url: 'http://keycloak-server/auth',
realm: 'my-realm',
clientId: 'my-app',
},
})
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:
(async () => {
await vueKeycloak.install(app, options);
app.use(initRouter());
app.mount('#app');
})();
Use Token
A helper function is exported to manage the access token.
getToken
| Function | Type | Description | | ---------------- | ------------------------------------------------------ | ---------------------------------------------------------------------- | | getToken | (minValidity?: number) => Promise<string> | 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.
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
<script setup>
import { computed } from 'vue'
import { useKeycloak } from '@josempgon/vue-keycloak'
const { hasRoles } = useKeycloak()
const hasAccess = computed(() => hasRoles(['RoleName']))
</script>
useKeycloak
The useKeycloak
function exposes the following data.
import { useKeycloak } from '@josempgon/vue-keycloak'
const {
// Reactive State
keycloak,
isAuthenticated,
isPending,
hasFailed,
token,
decodedToken,
username,
userId,
roles,
resourceRoles,
// Functions
hasRoles,
hasResourceRoles,
} = useKeycloak()
Reactive State
| State | Type | Description |
| --------------- | ------------------------------------------------------ | ------------------------------------------------------------------- |
| keycloak | Ref<
Keycloak
>
| Instance of the keycloak-js adapter. |
| isAuthenticated | Ref<boolean>
| If true
the user is authenticated. |
| isPending | Ref<boolean>
| If true
the authentication request is still pending. |
| hasFailed | Ref<boolean>
| If true
authentication request has failed. |
| token | Ref<string>
| Raw value of the access token. |
| decodedToken | Ref<
KeycloakTokenParsed
>
| Decoded value of the access token. |
| username | Ref<string>
| Username. Extracted from decodedToken['preferred_username']
. |
| userId | Ref<string>
| User identifier. Extracted from decodedToken['sub']
. |
| roles | Ref<string[]>
| List of the user's roles. |
| resourceRoles | Ref<Record<string, string[]>
| 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. |
License
Apache-2.0 Licensed | Copyright © 2021-present Gery Hirschfeld & Contributors