authentification OpenID Connect (Keycloak) : flux authorization code, state signé, validation du token ID via JWKS, provisioning automatique des utilisateurs

This commit is contained in:
fabien committed 2026-10-06 22:03:20 +02:00
1 parent 51bbb45b32
commit bedb6c98e7
15 files changed
+1057 -23

No files matched your search

+10
View File
@@ -21,8 +21,18 @@ export interface RegistrationData {
password: string
}
export interface OIDCProvider {
id: string
label: string
domain: string
clientId: string
wellknownUrl: string
}
export const authApi = {
register: (data: RegistrationData) => api.post<User>('/auth/register', data),
status: () => api.get<User>('/auth/status'),
login: (data: Credentials) => api.post<UserReponse>('/auth/login', data),
oidcProviders: () => api.get<OIDCProvider[]>('/auth/oidc/providers', { auth: false }),
oidcLoginUrl: (providerId: string) => `${import.meta.env.VITE_API_URL}/auth/oidc/login?provider=${encodeURIComponent(providerId)}`,
};
@@ -2,8 +2,9 @@
import logo from "$lib/assets/logo-txt.png"
import { auth, setToken } from '$lib/state/auth.svelte';
import { goto } from '$app/navigation';
import { authApi } from "$lib/api/endpoints/auth"
import { authApi, type OIDCProvider } from "$lib/api/endpoints/auth"
import { validateEmail } from "$lib/utilities/validators"
import { onMount } from "svelte"
type Credentials = {
email: string
@@ -17,6 +18,18 @@
validemail: false
})
let providers: OIDCProvider[] = $state([])
onMount(() => {
authApi.oidcProviders()
.then((res) => { providers = res ?? [] })
.catch(() => { providers = [] })
})
const oidcLogin = (providerId: string) => {
window.location.href = authApi.oidcLoginUrl(providerId)
}
const formSubmitEmail = () => {
credentials.validemail = validateEmail(credentials.email)
}
@@ -85,22 +98,21 @@
{/if}
<hr class="my-4">
{#if providers.length > 0}
<hr class="my-4">
<div class="grid grid-cols-[repeat(auto-fit,minmax(150px,1fr))] gap-4">
<button class="bt p-5 text-center" title="Connexion avec Google">
<i class="icon-google"></i>
</button>
<button class="bt p-5 text-center" title="Connexion avec Facebook">
<i class="icon-facebook"></i>
</button>
<button class="bt p-5 text-center" title="Connexion avec Github">
<i class="icon-github"></i>
</button>
<button class="bt p-5 text-center" title="Connexion avec Apple">
<i class="icon-apple"></i>
</button>
</div>
<div class="grid grid-cols-[repeat(auto-fit,minmax(150px,1fr))] gap-4">
{#each providers as provider (provider.id)}
<button
class="bt p-5 text-center"
title="Connexion avec {provider.label}"
onclick={() => oidcLogin(provider.id)}
>
{provider.label}
</button>
{/each}
</div>
{/if}
</div>
</div>