DEV Community

Cover image for How to connect keycloak and Nuxt
Ismael Garcia
Ismael Garcia

Posted on

How to connect keycloak and Nuxt

While working in an internal project, I got the task of getting the connection between keycloak and our nuxt application.

After an hour of research, I found two feasible options to get this working fast and easy.

→ Using the keycloak-js

  1. manage the keycloak manually
<script setup> import Keycloak from 'keycloak-js' import { useKeycloak } from '@/stores/keycloak' useHead({ title: 'Home page' }) const config = useRuntimeConfig() const store = useKeycloak() const state = reactive({ loggedIn: false }) if (config.public.keycloakDisabled) { state.loggedIn = true } else { const initOptions = { url: config.public.keycloakUrl, realm: config.public.keycloakRealm, clientId: config.public.keycloakClientId, onLoad: 'login-required' } const keycloak = new Keycloak(initOptions) keycloak .init({ onLoad: initOptions.onLoad }) .then((auth) => { if (!auth) { window.location.reload() } else { store.setup(keycloak) state.loggedIn = true } }) } </script> <template> <div> <div v-if="state.loggedIn"> <Header /> <NuxtPage /> </div> </div> </template> 
Enter fullscreen mode Exit fullscreen mode

With this option you don’t have public pages

→ Using # Nuxt OpenID-Connect Module
that is using node-openid-client

With this option, you can have public routes by just extending the nuxt-config

openidConnect: { addPlugin: true, op: { issuer: "http://keycloak:8080/realms/dev-realm", // change to your OP addrress clientId: "CLIENT_ID", clientSecret: "SECRET_KEY", callbackUrl: "", // optional scope: ["email", "profile", "address"], }, config: { debug: true, response_type: "code", secret: "oidc._sessionid", cookie: { loginName: "" }, cookiePrefix: "oidc._", cookieEncrypt: true, cookieEncryptKey: "SECRET_KEY", cookieEncryptIV: "ab83667c72eec9e4", cookieEncryptALGO: "aes-256-cbc", cookieMaxAge: 24 * 60 * 60, // default one day cookieFlags: { access_token: { httpOnly: true, secure: false, }, }, }, }, 
Enter fullscreen mode Exit fullscreen mode

Then create a middleware/auth.global.ts

export default defineNuxtRouteMiddleware((to, from) => { if (import.meta.server) { return; } const isAuthRequired = to.meta.auth || false; const oidc = useOidc(); if (isAuthRequired && !oidc.isLoggedIn) { oidc.login(to.fullPath); } }); 
Enter fullscreen mode Exit fullscreen mode

for public pages, you can set the meta attribute:

<script lang="ts" setup> /** * * Component Description:Desc * * @author Reflect-Media <ismael@leamsigc.com> * @version 0.0.1 * * @todo [ ] Test the component * @todo [ ] Integration test. * @todo [✔] Update the typescript. */ definePageMeta({ auth: false, layout: "public-view", }); </script> <template> <div class="grid place-items-center"> <RegistrationForm /> </div> </template> <style scoped></style> 
Enter fullscreen mode Exit fullscreen mode

for the pages that need authentication:

<script lang="ts" setup> /** * * Component Description:Desc * * @author Reflect-Media <reflect.media GmbH> * @version 0.0.1 * * @todo [ ] Test the component * @todo [ ] Integration test. * @todo [✔] Update the typescript. */ definePageMeta({ auth: true, }); </script> <template> <div>content</div> </template> <style scoped></style> 
Enter fullscreen mode Exit fullscreen mode

The other option is to create

  • layouts/default.vue → that set the auth to true by default
  • layouts/publicView.vue → will set the auth to false.

Resources:

Module
Example with keycloak-js

**Happy hacking!

Working on the audio version

The Loop VueJs Podcast

Top comments (1)

Collapse
 
leamsigc profile image
Ismael Garcia

Is there a better way to do this? do you have any questions or want to see the example repo, just let me know