How to integrate SSO Keycloak Directus to Front End?

Dear All,
I have a directus that already integrate to SSO Keycloak with this settings:

"AUTH_PROVIDERS": "keycloak",
"AUTH_KEYCLOAK_DRIVER": "openid",
"AUTH_KEYCLOAK_CLIENT_ID": "directus",
"AUTH_KEYCLOAK_CLIENT_SECRET": "secret",
"AUTH_KEYCLOAK_ISSUER_URL": "https://sso.domain.net/realms/realmdomain/.well-known/openid-configuration",
"AUTH_KEYCLOAK_IDENTIFIER_KEY": "email",
"AUTH_KEYCLOAK_ALLOW_PUBLIC_REGISTRATION": true,
"AUTH_KEYCLOAK_REDIRECT_ALLOW_LIST": "http://localhost:3000",
"AUTH_KEYCLOAK_LABEL": "SSO-Domain-ID",
"ACCESS_TOKEN_TTL": "15m",
"REFRESH_TOKEN_TTL": "7d",
"REFRESH_TOKEN_COOKIE_SECURE": false,
"REFRESH_TOKEN_COOKIE_SAME_SITE": "lax",
"REFRESH_TOKEN_COOKIE_NAME": "directus_refresh_token",
"SESSION_COOKIE_TTL": "1d",
"SESSION_COOKIE_SECURE": false,
"SESSION_COOKIE_SAME_SITE": "lax",
"SESSION_COOKIE_NAME": "directus_session_token",

With those settings, users can login to directus admin UI with their SSO credentials. It’s done.

Now, I want to integrate my frontend with SSO keycloak and directus as backend. I tried using same client with directus, but after successful login in SSO Keycloak login page, it redirected back to directus admin site, not frontend site.

I also tried using new client, dedicated for frontend site. So redirect_URI set to http://localhost:3000/api/auth/callback/keycloak and when i click “login with SSO”, it redirected to Keycloak login page as it should be.

This is my /api/auth/callback/keycloak/route.ts (I’m using nextjs 13.5.1):

import { NextRequest } from 'next/server';

export const dynamic = 'force-dynamic';

export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    const code = searchParams.get('code');
    const error = searchParams.get('error');

    if (error) {
      return Response.json({ error }, { status: 400 });
    }
    if (!code) {
      return Response.json({ error: 'Missing authorization code' }, { status: 400 });
    }

    // Exchange code for tokens
    const tokenRes = await fetch('https://sso.domain.net/realms/realmdomain/protocol/openid-connect/token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        client_id: 'portaldev',
        grant_type: 'authorization_code',
        code,
        redirect_uri: 'http://localhost:3000/api/auth/callback/keycloak',
      }),
    });

    if (!tokenRes.ok) {
      const err = await tokenRes.text();
      return Response.json({ error: 'Failed to exchange code for tokens', details: err }, { status: 400 });
    }
    const tokens = await tokenRes.json();

    // Fetch user info
    const userinfoRes = await fetch('https://sso.domain.net/realms/realmdomain/protocol/openid-connect/userinfo', {
      headers: {
        Authorization: `Bearer ${tokens.access_token}`,
      },
    });
    const userinfo = userinfoRes.ok ? await userinfoRes.json() : null;

    // Set cookie for access_token
    const cookie = `kc_access_token=${tokens.access_token}; Path=/; HttpOnly; Secure; Max-Age=${tokens.expires_in}`;
    // Redirect to homepage after SSO
    return new Response(null, {
      status: 302,
      headers: {
        'Set-Cookie': cookie,
        'Location': '/',
      },
    });
  } catch (err) {
    console.error('Keycloak SSO callback error:', err);
    return Response.json({ error: 'Internal server error' }, { status: 500 });
  }
} 

But it stuck, redirected to unauth homepage.

How to do it correctly?

After some test and trials, I’m stuck with this conditions:
Directus: 11.9.2
Keycloak: 26.2.4
Nextjs: 13.5.1

  1. I see that in worked Directus Admin UI, “Login with Keycloak” href to https://directusdomain/auth/login/keycloak?redirect=https://directusdomain/admin/login?=continue
  2. But I want to redirect to frontend again after successful keycloak login. So I tried: https://directusdomain/auth/login/keycloak?redirect=https://localhost:3000 but it failed with this errror: Invalid Payload, https://localhost:3000 can’t be used to redirect after login. But when I change “redirect” to “redirect_url” (https://directusdomain/auth/login/keycloak?redirect_url)=https://localhost:3000) it work, it redirected to sso keycloak login page.
  3. But, after success keycloak login, it stay in this kind of link: https://directusdomain/auth/login/keycloak/callback?state=fV7Td1q9redacted&iss=https%3A%2F%2Fsso.domain.net%2Frealms%2Fdomainrealm&code=34a22080-aredacted with this JSON data shown up in browser:
    {“data”:{“access_token”:“eyA”,“refresh_token”:“bn-V4A”,“expires”:86400000}}
    And I tested the refresh_token via postman to /auth/refresh, it worked!

Any ideas, how to get it done from here?