@lgibbs/keycloak-auth
v2.0.0
Published
"Framework-agnostic Javascript Keycloak auth client"
Downloads
8
Maintainers
Readme
keycloak-auth
Framework-agnostic JavaScript Keycloak authentication client.
Installation
npm install @lgibbs/keycloak-authUsage
Plain JavaScript (No Framework)
<!DOCTYPE html>
<html>
<head>
<script type="module" src="/path/to/keycloak-auth.js"></script>
</head>
<body>
<div id="app">Loading…</div>
<script type="module">
import { initAuth, subscribe, login } from '/path/to/keycloak-auth.js';
await initAuth({
url: 'https://kc.example.com/auth',
realm: 'myrealm',
clientId: 'my-client',
onLoad: 'login-required',
silentCheckUri: `${window.origin}/silent-check.html`
});
subscribe(({ authenticated, token }) => {
const el = document.getElementById('app');
if (authenticated) {
el.textContent = `Logged in! Token: ${token.slice(0,10)}…`;
} else {
el.innerHTML = `<button id="login">Log in</button>`;
document.getElementById('login').onclick = login;
}
});
</script>
</body>
</html>React
import React, { useEffect, useState } from 'react';
import { initAuth, subscribe, login, logout } from 'keycloak-auth';
function App() {
const [auth, setAuth] = useState({ authenticated: false });
useEffect(() => {
initAuth({
url: process.env.REACT_APP_KC_URL,
realm: process.env.REACT_APP_KC_REALM,
clientId: process.env.REACT_APP_KC_CLIENT_ID,
onLoad: 'check-sso',
silentCheckUri: `${window.location.origin}/silent-check.html`
});
const unsub = subscribe(setAuth);
return unsub;
}, []);
if (!auth.authenticated) {
return <button onClick={login}>Log in</button>;
}
return (
<div>
<p>Welcome! Token: {auth.token.substring(0, 10)}…</p>
<button onClick={logout}>Log out</button>
</div>
);
}Vue 3
import { createApp } from 'vue';
import App from './App.vue';
import { initAuth, subscribe } from 'keycloak-auth';
initAuth({
url: import.meta.env.VITE_KC_URL,
realm: import.meta.env.VITE_KC_REALM,
clientId: import.meta.env.VITE_KC_CLIENT_ID,
onLoad: 'login-required'
});
const app = createApp(App);
app.provide('kcSubscribe', subscribe);
app.mount('#app');<template>
<div v-if="auth.authenticated">
<p>Welcome—token: {{ auth.token.substr(0,10) }}…</p>
<button @click="logout">Logout</button>
</div>
<div v-else>
<button @click="login">Login</button>
</div>
</template>
<script>
import { inject, onMounted, ref } from 'vue';
import { login, logout } from 'keycloak-auth';
export default {
setup() {
const auth = ref({});
const kcSubscribe = inject('kcSubscribe');
onMounted(() => kcSubscribe(a => (auth.value = a)));
return { auth, login, logout };
}
};
</script>Angular
import { Injectable } from '@angular/core';
import * as kcAuth from 'keycloak-auth';
@Injectable({ providedIn: 'root' })
export class KeycloakService {
init() {
return kcAuth.initAuth({
url: environment.kcUrl,
realm: environment.kcRealm,
clientId: environment.kcClientId
});
}
login() { kcAuth.login(); }
logout() { kcAuth.logout(); }
getToken() { return kcAuth.getToken(); }
subscribe(cb: any) { return kcAuth.subscribe(cb); }
}import { Component, OnInit } from '@angular/core';
import { KeycloakService } from './keycloak.service';
@Component({
selector: 'app-root',
template: `
<ng-container *ngIf="auth.authenticated; else loginTpl">
<p>Logged in! Token: {{ auth.token | slice:0:10 }}…</p>
<button (click)="logout()">Logout</button>
</ng-container>
<ng-template #loginTpl>
<button (click)="login()">Login</button>
</ng-template>
`
})
export class AppComponent implements OnInit {
auth = { authenticated: false, token: null };
constructor(private kc: KeycloakService) {}
async ngOnInit() {
await this.kc.init();
this.kc.subscribe(a => (this.auth = a));
}
login() { this.kc.login(); }
logout() { this.kc.logout(); }
}API Reference
- initAuth(config): Initializes Keycloak with
{ url, realm, clientId, onLoad?, silentCheckUri? }. - login(): Redirects the browser to Keycloak’s login page.
- logout(): Logs out and clears the auth state.
- getToken(): Returns the current token or
null. - subscribe(callback): Subscribes to auth state changes (
{ authenticated, token, tokenParsed }). Returns an unsubscribe function.
Development & Build
Optional Rollup Build
To generate UMD & ESM bundles:
Install dev dependencies:
npm install --save-dev rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs rollup-plugin-terserCreate
rollup.config.js:import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import { terser } from 'rollup-plugin-terser'; export default { input: 'keycloak-auth.js', output: [ { file: 'dist/keycloak-auth.esm.js', format: 'esm' }, { file: 'dist/keycloak-auth.umd.js', format: 'umd', name: 'KCAuth' } ], plugins: [resolve(), commonjs(), terser()] };Update
package.json:"scripts": { "build": "rollup -c" }, "main": "dist/keycloak-auth.umd.js", "module": "dist/keycloak-auth.esm.js", "unpkg": "dist/keycloak-auth.umd.js"Run:
npm run build
Publishing to npm
Login:
npm loginPublish:
npm publish --access publicVersioning: bump version in
package.json, tag in git (git tag v1.0.1 && git push --tags), then re-publish.
License
MIT
