Keycloak logout

I am new to Keycloak, but I have set up a Keycloak server, the installation, configuration, and access to my web application.

Authentication goes through a custom SPI for read-only access to a database managed by our web application.
No proxy, just a web app using ExtJS and PHP on Apache2 with mod_auth_openid.

The problem — something I didn’t think would be this complicated to me — is understanding what a logout is and how to do it with Keycloak.

Despite, I’ve already read some of the documentation and examples on the subject, a lot of them are new to me, I feel like I’ve tried everything, and I still don’t understand the expected behavior.

I was deleting/clearing cookies, but it does not seem to be working with the Keycloak cookies (both in JS and PHP).

document.cookie.split(";").forEach(cookie => {
    document.cookie = cookie.replace(/^ +/, "")
    .replace(/=.*/, 
            "=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/");
});
foreach($_COOKIE as $name => $value) {
        setcookie($name, '', time()-3600, '/');
}
header("Location: /");

I’m looking forward to work with the logout URI :
“https://1.1.1.1/realms/dev/protocol/openid-connect/logout”

I saw some example with what it seems to be a depreciated method to me, /auth/.

Whether I call it via POST or GET, manually through my browser or in my PHP, with or without parameters, it does not log the user out.

Here is the PHP code I am using to try the logout part:


$realm = "dev";
$keycloak_base_url = "https://1.1.1.1:8443";
$redirect_uri = "https://1.1.1.1/app/";
$client_id = "mySuperclient";
$client_secret = "mySuperSecret";


$refresh_token = $_SERVER['OIDC_refresh_token'];
$access_token = $_SERVER['OIDC_access_token'];
$logout_url = "$keycloak_base_url/realms/$realm/protocol/openid-connect/logout";

$data = [
    'client_id' => $client_id,
    'refresh_token' => $refresh_token,
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $logout_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curl_error = curl_error($ch);
curl_close($ch);

if ($http_code === 204) {
    echo "Successful! Redirecting...";
    header("Location: /app/");  
    exit();
} else {
    echo "Failed! HTTP Code: $http_code <br>";
    echo "<pre>" . htmlspecialchars($response) . "</pre><br>";
}

OS : Debian 12.9
PHP version: 8.2.26
Keycloak : 26.1.0 (bare metal install)
mod-auth-openidc :2.4.12.3

I don’t really know, but everything seems to be good, the client, scopes and redirect uris works, all that remains is the logout part…

EDIT1: The use of

header ("Location: $logout_url");

redirects me to a Keycloak logout confirmation page. Even with a manual validation, I still can access my web app without login.

I think I have to add some data to that logout redirect, but can’t figure out what is necessary.