Skip to content

OIDC Session Logout — RP-Initiated and OP-Initiated Logout Mechanisms

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about OIDC Session Logout. We cover key concepts, practical examples, and best practices to help you master this topic.

OIDC defines two logout mechanisms: RP-initiated logout where a client application triggers logout, and OP-initiated logout where the provider logs the user out of all applications simultaneously.

What You'll Learn

  • How RP-initiated logout works with the end_session_endpoint
  • How OP-initiated logout uses front-channel and back-channel mechanisms
  • How to implement proper logout in your OIDC application

Why It Matters

Improper logout implementation leaves users vulnerable. If your app clears its local session but does not notify the provider, the user's SSO session persists. An attacker with access to the user's computer can re-enter any app without credentials. Proper logout terminates all sessions.

Real-World Use

A user clicks "Logout" on DodaMail. DodaMail redirects to the provider's end_session_endpoint with the ID token hint. The provider clears the SSO session and uses front-channel logout to notify DodaDrive and DodaCalendar via iframes, logging the user out of all services simultaneously.

sequenceDiagram
    participant User
    participant App as DodaMail (RP)
    participant Provider as OIDC Provider
    participant App2 as DodaDrive (RP2)

    User->>App: Click Logout
    App->>Provider: Redirect to end_session_endpoint
    Note over Provider: Clear SSO Session
    Provider->>App: Front-Channel Logout (iframe)
    Provider->>App2: Front-Channel Logout (iframe)
    App-->>User: Logged Out
    App2-->>User: Logged Out

RP-Initiated Logout

from flask import Flask, redirect, session
import urllib.parse

app = Flask(__name__)

@app.route('/logout')
def logout():
    # Build RP-initiated logout URL
    end_session_endpoint = "https://accounts.example.com/connect/endsession"
    id_token_hint = session.get('id_token')

    params = {
        "id_token_hint": id_token_hint,
        "post_logout_redirect_uri": "https://doda.example.com/logged-out",
        "state": "logout-state-abc"
    }

    logout_url = f"{end_session_endpoint}?{urllib.parse.urlencode(params)}"

    # Clear local session
    session.clear()

    # Redirect to provider for global logout
    return redirect(logout_url)

OP-Initiated Logout (Provider Side)

The provider can initiate logout when an admin terminates a session or the user logs out from another app:

# Provider-side logout notification
def handle_op_initiated_logout(user_id, logout_token, client_apps):
    """OP-initiated logout: notify all apps via front-channel or back-channel"""
    for client in client_apps:
        if client.get('frontchannel_logout_uri'):
            # Front-channel: browser loads iframe
            send_frontchannel_logout(
                client['frontchannel_logout_uri'],
                logout_token
            )
        elif client.get('backchannel_logout_uri'):
            # Back-channel: server-to-server request
            requests.post(
                client['backchannel_logout_uri'],
                json={"logout_token": logout_token}
            )

Handling Logout Callback

// Front-channel logout handler (loaded in iframe)
async function handleFrontChannelLogout() {
  const urlParams = new URLSearchParams(window.location.search);
  const logoutToken = urlParams.get('logout_token');

  if (logoutToken) {
    // Clear all auth data
    localStorage.removeItem('access_token');
    localStorage.removeItem('id_token');
    sessionStorage.clear();

    // Notify the main window
    window.parent.postMessage('logged_out', '*');

    // Respond with a 1x1 transparent GIF
    document.write('<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">');
  }
}

Common Mistakes

1. Only Clearing Local Session

Clearing the local session without calling the provider's end_session_endpoint leaves the SSO session active. The user can re-enter without credentials.

2. Omitting the id_token_hint

Without the id_token_hint, the provider cannot identify which session to terminate and may show a logout confirmation page instead of logging out immediately.

3. Not Registering post_logout_redirect_uri

The provider validates post_logout_redirect_uri against the registered list. Use an unregistered URI and the provider will reject the redirect.

4. Forgetting to Handle the Logout Token

OP-initiated logout sends a logout token. Your app must validate this token (signature, issuer, expiration) before processing the logout.

5. Not Supporting Both Logout Mechanisms

Support both RP-initiated (user clicks logout in your app) and OP-initiated (provider logs user out) for complete logout coverage.

Practice Questions

  1. What is RP-initiated logout?
  2. What is the id_token_hint used for in logout?
  3. How does OP-initiated logout work?
  4. What is a front-channel logout URI?
  5. What is a back-channel logout URI?

Answers

  1. Logout triggered by the relying party (client application) redirecting to the provider. 2. It tells the provider which session to terminate. 3. The provider sends logout notifications to all active applications when a session ends. 4. A URI loaded in an iframe for browser-based logout notification. 5. A server-to-server endpoint for logout notification without browser involvement.

Challenge

Build a logout coordinator that when triggered from any one of three demo applications, performs RP-initiated logout to the provider, waits for front-channel logout confirmations from all apps, and displays a dashboard showing which apps have acknowledged the logout and which have not.

FAQ

What is RP-initiated logout?

Logout initiated by the relying party (your app) redirecting the user to the provider's end_session_endpoint.

What is OP-initiated logout?

Logout initiated by the provider, notifying all active applications via front-channel or back-channel URIs.

What is the id_token_hint in logout?

The ID token of the session to be terminated, allowing the provider to identify and end the correct session.

What is front-channel logout?

The provider loads an iframe pointing to each app's frontchannel_logout_uri to clear sessions in the browser.

What is back-channel logout?

The provider sends a direct HTTP POST to each app's backchannel_logout_uri without browser involvement.

Mini Project

Create a complete logout system with three sample applications sharing the same OIDC provider. Implement RP-initiated logout from each app, OP-initiated logout that triggers when any app logs out, and a session monitor showing real-time logout propagation.

What's Next

  • Learn about the check_session_iframe for cross-application session monitoring
  • Explore front-channel logout implementation details
  • Continue to back-channel logout for server-to-server session termination

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro