Keycloak-Angular - Redirect to "Confirm Logout" page when logging out after a page refresh

111 Views Asked by At

When utilizing this.keycloak.logout() when i am using identity Provider IDP , it redirects to a confirmation page. I want to directly get redirected to login page and the session is ended. The thing is when i don't confirm, it doesn't delete the session from the keyloak dashboard.

2

There are 2 best solutions below

1
Prifulnath On

Here is a simple solution. In order to logout and redirect directly to the page you want, you can mention the redirect URI and enable direct redirection from client configuration, which will directly redirect your page.

public logout() {
  this.keycloak.logout({
    redirectUri: 'your/url/here',
  });
}

example for my redirect URL : http://localhost:4200/home

Also in your client configuration Front channel logout should be enabled.

enter image description here

Description of Front channel logout in keycloak

When true, logout requires a browser redirect to client. When false, server performs a background invocation for logout.

0
dannybee82 On

Another solution is to call the end_session_endpoint or use the REST API.

To see which endpoints are available/enabled see your keycloak-installation:

{protocol}://{domain}:{port}/realms/{realm-name}/.well-known/openid-configuration

When using the REST API, there are differences between versions.

Version 22.x.x and higher uses:

POST /admin/realms/{realm}/users/{id}/logout

But version 21.x.x and lower uses:

POST /{realm}/users/{id}/logout

Calling this endpoint will:

Remove all user sessions associated with the user Also send notification to all clients that have an admin URL to invalidate the sessions for the particular user.

More information: Keycloak Documentation

Example alternative logout-Service (but the code can be improved):

import { HttpClient } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
import { KeycloakService } from 'keycloak-angular';
import { Observable } from 'rxjs';

export interface LogoutRequestInterface {
  id: string,
  realm: string
}

@Injectable({
  providedIn: 'root'
})
export class KeycloakLogoutService {

  private http = inject(HttpClient);
  private readonly keycloak = inject(KeycloakService);

  logout() : Observable<void> {
    const keycloakInstance = this.keycloak.getKeycloakInstance();
    //Uncomment below to for debugging purposes.
    //console.log(keycloakInstance);
    
    const req: LogoutRequestInterface = { 
      id: keycloakInstance.profile?.id ?? '',
       realm: keycloakInstance.realm ?? ''
    };

    //Below: admin/ can be omitted for Keycloak versions 21.x.x and lower.
    let url: string = `${keycloakInstance.authServerUrl}/admin/realms/${keycloakInstance.realm}/users/${keycloakInstance.profile?.id}/logout`;
    return this.http.post<void>(url, {req});
  }

}

Useage in the component:

logout() : void {
this.keycloakLogout.logout().subscribe({
  next: () => {        
    //Do stuff here.       
    this.keycloak.logout();
  }, 
  error: () => {
    console.log('Unable to logout.');
  }      
});

}

I hope this helps.