Integration with Frontend

Prerequisites

To integrate Keycloak with the platform-frontend or the cloud-ui we assume the following testing environment (see Introduction and Authentication Token):

clientId        <a-client-id>
clientSecret    *****

Together with a random string for securing cookies the entire configuration, i.e. .env.local should look like:

AUTH_ORIGIN = http://localhost:8080

NUXT_APP_URL = http://localhost:8080
NUXT_AUTH_SECRET = a-long-random-string
NUXT_KEYCLOAK_CLIENT_ID = a-client-id
NUXT_KEYCLOAK_CLIENT_SECRET = ***** (see SharePoint)
NUXT_KEYCLOAK_ISSUER = https://auth.pistis-market.eu/realms/PISTIS

The example client used in the above NuxtJS configuration is configured with valid redirect URL's: http://localhost:8080/* and http://127.0.0.1:8080/* Also * is configured as valid post logout redirect URIs and Web origins (to override CSRF protection for local environments).

Then, you need to start the frontend project with: pnpm run dev --dotenv .env.local

Nuxt configuration

Edit file nuxt.config.ts to enable Keycloak:

auth.globalAppMiddleware.isEnable: true

Sample user to test

For the example purposes, a demo user with username: test is considered:

Username: test
Password: *****

The received user authentication token can be accessed via:

    const headers = useRequestHeaders(['cookie']) as HeadersInit;
    const { data: token } = await useFetch('/api/token', { headers });

and the received token can be subsequently used to a request (i.e. an API call) via:

    const apiUri = 'https://pistis-market.eu/srv/service-name/api-call';
    const response = await useFetch(apiUri, {
        method: 'get',
        headers: {
            Authorization: `Bearer ${token.value?.jwt}`,
            Accept: 'application/json',
        },
    });

Token contents

In case you need to visualise the contents from the frontend (i.e. just for debugging purposes) you may use jwt-decode function with the following steps:

  1. Install jwt-decode
pnpm install jwt-decode
  1. Sample .vue page to visualize token contents:
<script setup lang="ts">
import { jwtDecode } from 'jwt-decode';

const headers = useRequestHeaders(['cookie']) as HeadersInit;
const { data: token } = await useFetch('/api/token', { headers });

function getDecodedAccessToken(at: any): any {
    try {
        return jwtDecode(at);
    } catch (Error) {
        return null;
    }
}

const idTokenInfo = await getDecodedAccessToken(token.value?.id_token); // decode token
const accessTokenInfo = await getDecodedAccessToken(token.value?.access_token); // decode token
</script>

<template>
    <div class="w-full h-full">
        <div class="flex flex-col w-full mt-8 p-6">
            <hr style="height: 50px" />
            <h1>Decompiled ID Token</h1>
            <pre>{{ idTokenInfo }}</pre>
            <hr style="height: 50px" />
            <h1>Decompiled Access Token (for account audience)</h1>
            <pre>{{ accessTokenInfo }}</pre>
        </div>
    </div>
</template>