fix(auth): restore keycloak sign-in for NodePort access
All checks were successful
CI Pipeline / Backend Build & Test (push) Successful in 58s
CI Pipeline / Frontend Lint, Test & Build (push) Successful in 28s
CI Pipeline / Infrastructure Validation (push) Successful in 4s

Trust external host for Auth.js, provide missing frontend auth env/secrets, and submit a proper CSRF-backed sign-in POST so browser login reaches Keycloak reliably.
This commit is contained in:
WorkClub Automation
2026-03-13 06:52:18 +01:00
parent d4f09295be
commit 9cb80e4517
3 changed files with 58 additions and 3 deletions

View File

@@ -1,7 +1,7 @@
'use client'; 'use client';
import { useEffect, Suspense } from 'react'; import { useEffect, Suspense } from 'react';
import { signIn, signOut, useSession } from 'next-auth/react'; import { signOut, useSession } from 'next-auth/react';
import { useRouter, useSearchParams } from 'next/navigation'; import { useRouter, useSearchParams } from 'next/navigation';
import { Card, CardHeader, CardTitle, CardContent, CardFooter } from '@/components/ui/card'; import { Card, CardHeader, CardTitle, CardContent, CardFooter } from '@/components/ui/card';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
@@ -18,8 +18,33 @@ function LoginContent() {
} }
}, [status, router]); }, [status, router]);
const handleSignIn = () => { const handleSignIn = async () => {
signIn('keycloak', { callbackUrl: '/dashboard' }); const csrfResponse = await fetch('/api/auth/csrf');
const csrfPayload = await csrfResponse.json() as { csrfToken?: string };
if (!csrfPayload.csrfToken) {
window.location.href = '/api/auth/signin?callbackUrl=%2Fdashboard';
return;
}
const form = document.createElement('form');
form.method = 'POST';
form.action = '/api/auth/signin/keycloak';
const csrfInput = document.createElement('input');
csrfInput.type = 'hidden';
csrfInput.name = 'csrfToken';
csrfInput.value = csrfPayload.csrfToken;
form.appendChild(csrfInput);
const callbackInput = document.createElement('input');
callbackInput.type = 'hidden';
callbackInput.name = 'callbackUrl';
callbackInput.value = `${window.location.origin}/dashboard`;
form.appendChild(callbackInput);
document.body.appendChild(form);
form.submit();
}; };
const handleSwitchAccount = () => { const handleSwitchAccount = () => {

View File

@@ -62,3 +62,31 @@ spec:
configMapKeyRef: configMapKeyRef:
name: workclub-config name: workclub-config
key: keycloak-url key: keycloak-url
- name: NEXT_PUBLIC_KEYCLOAK_ISSUER
valueFrom:
configMapKeyRef:
name: workclub-config
key: keycloak-authority
- name: NEXTAUTH_URL
value: "http://192.168.240.200:30080"
- name: AUTH_TRUST_HOST
value: "true"
- name: NEXTAUTH_SECRET
valueFrom:
secretKeyRef:
name: workclub-secrets
key: nextauth-secret
- name: KEYCLOAK_CLIENT_ID
value: "workclub-app"
- name: KEYCLOAK_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: workclub-secrets
key: keycloak-client-secret
- name: KEYCLOAK_ISSUER
valueFrom:
configMapKeyRef:
name: workclub-config
key: keycloak-authority
- name: KEYCLOAK_ISSUER_INTERNAL
value: "http://workclub-keycloak/realms/workclub"

View File

@@ -9,3 +9,5 @@ stringData:
keycloak-db-password: "keycloakpass" keycloak-db-password: "keycloakpass"
keycloak-admin-username: "admin" keycloak-admin-username: "admin"
keycloak-admin-password: "adminpassword" keycloak-admin-password: "adminpassword"
keycloak-client-secret: "dev-secret-workclub-api-change-in-production"
nextauth-secret: "dev-secret-change-in-production-use-openssl-rand-base64-32"