Skip to content

OIDC Post-Logout Redirect URI — Controlling the Destination After Session Termination

DodaTech Updated 2026-06-28 4 min read

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

The post_logout_redirect_uri parameter in Openid Connect specifies where the provider redirects the user after successful logout, allowing applications to return users to a specific page instead of a generic provider landing page.

What You'll Learn

  • How to configure post-logout redirect URIs in client registration
  • How to use the parameter in RP-initiated logout
  • Security considerations for preventing open redirect attacks

Why It Matters

Without a post-logout redirect, users land on the provider's generic logout page. This creates a poor user experience and loses the brand context. A properly configured post-logout redirect returns users to your application's goodbye page or login page, maintaining brand continuity.

Real-World Use

A user logs out of DodaBrowser. The provider redirects them to https://doda.example.com/logged-out which displays a friendly message, options to log back in, and links to DodaTech's other products. Without this, the user would see the provider's generic "You are logged out" page.

flowchart LR
    A["User clicks\nLogout"] --> B["OIDC Provider\nend_session_endpoint"]
    B --> C["Provider clears\nSSO session"]
    C --> D["Redirect to\npost_logout_redirect_uri"]
    D --> E["https://doda.example.com\n/logged-out"]
    E --> F["Show goodbye page\n+ login button"]
    style D fill:#dbeafe,stroke:#2563eb
    style E fill:#bbf7d0,stroke:#16a34a

Configuring Post-Logout Redirect URIs

Register allowed post-logout redirect URIs during client registration:

{
  "client_id": "doda-browser",
  "redirect_uris": ["https://doda.example.com/callback"],
  "post_logout_redirect_uris": [
    "https://doda.example.com/logged-out",
    "https://doda.example.com/login"
  ]
}

Using the Parameter in Logout

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

app = Flask(__name__)

@app.route('/logout')
def logout():
    end_session_endpoint = "https://accounts.example.com/connect/endsession"
    id_token = session.get('id_token')

    # Build logout URL with post-logout redirect
    params = {
        "id_token_hint": id_token,
        "post_logout_redirect_uri": "https://doda.example.com/logged-out",
        "state": "logout-nonce-abc"
    }

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

    # Clear local session
    session.clear()

    return redirect(logout_url)

Handling the Post-Logout Redirect

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/logged-out')
def logged_out():
    """Displayed after successful OIDC logout"""
    state = request.args.get('state')

    # Verify state matches the one we sent
    expected_state = "logout-nonce-abc"
    if state != expected_state:
        app.logger.warning("Logout state mismatch")

    return render_template('logged_out.html', context={
        'message': 'You have been successfully logged out.',
        'login_url': '/login',
        'home_url': '/'
    })
<!-- templates/logged_out.html -->
<div class="logout-container">
  <h1>You're logged out</h1>
  <p>Your session has been terminated successfully.</p>
  <p>You have been logged out of all DodaTech applications.</p>
  <div class="actions">
    <a href="{{ login_url }}" class="button">Log Back In</a>
    <a href="{{ home_url }}" class="button secondary">Go to Home</a>
  </div>
</div>

Security Validation

Always validate the post_logout_redirect_uri server-side to prevent open redirect attacks:

import re
from flask import Flask, abort

app = Flask(__name__)

ALLOWED_POST_LOGOUT_URIS = [
    "https://doda.example.com/logged-out",
    "https://doda.example.com/login",
    "https://doda.example.com"
]

def validate_post_logout_uri(uri):
    """Validate that the URI is in the allowed list"""
    if uri in ALLOWED_POST_LOGOUT_URIS:
        return True

    # Pattern match for wildcard support
    for allowed in ALLOWED_POST_LOGOUT_URIS:
        pattern = re.escape(allowed).replace(r'\*', '.*')
        if re.match(f"^{pattern}$", uri):
            return True
    return False

@app.route('/perform-logout')
def perform_logout():
    post_logout_uri = request.args.get('post_logout_redirect_uri')

    if post_logout_uri and not validate_post_logout_uri(post_logout_uri):
        abort(400, "Invalid post-logout redirect URI")

    # Proceed with logout
    return redirect(post_logout_uri or "https://doda.example.com/logged-out")

Common Mistakes

1. Not Registering Post-Logout URIs

The provider rejects unregistered redirect URIs. Register all allowed post-logout URIs during client registration.

2. Using Open Redirects

Without validation, an attacker can craft a logout URL that redirects to a malicious site. Always validate the redirect URI server-side.

3. Ignoring the State Parameter

The state parameter in the logout request prevents CSRF Attacks on the redirect. Validate it when the redirect arrives.

4. Redirecting to External Domains

Post-logout redirect URIs must be on the same domain or explicitly registered. Do not redirect to third-party domains.

5. Not Handling the Missing Redirect Case

If no post_logout_redirect_uri is specified, the provider shows its own page. Handle this gracefully in your application.

Practice Questions

  1. What does the post_logout_redirect_uri parameter do?
  2. Where do you register allowed post-logout redirect URIs?
  3. Why is redirect URI validation important?
  4. What is the purpose of the state parameter in logout?
  5. What happens if you omit post_logout_redirect_uri?

Answers

  1. It specifies where the provider redirects after logout. 2. In the client registration metadata (post_logout_redirect_uris). 3. To prevent open redirect attacks that send users to malicious sites. 4. It prevents CSRF attacks on the logout redirect. 5. The provider shows its own generic logout page.

Challenge

Build a logout redirect validator that checks post-logout URIs against a configured whitelist, supports glob patterns, logs violations, and returns a safe default redirect URI when validation fails.

FAQ

What is the post_logout_redirect_uri?

A parameter in the logout request that specifies where the provider redirects after session termination.

Do I need to register post-logout URIs?

Yes. The provider only redirects to URIs registered in the client metadata.

What is the security risk of post-logout redirects?

Without validation, an attacker can create an open redirect to phishing sites.

Can I use wildcards in post-logout URIs?

Some providers support wildcard patterns. Check your provider's documentation.

What should I show on the logged-out page?

A clear message that logout is complete, a login button, and links to related resources.

Mini Project

Build a logout flow with post-logout redirect handling that includes: a configuration UI for managing allowed redirect URIs, server-side validation with security logging, a branded logged-out page with options to re-authenticate, and support for multiple language versions of the logged-out page.

What's Next

  • Review all OIDC concepts in the complete project
  • Explore claims mechanisms in the claims request lesson
  • Continue to the next API topic: OIDC vs OAuth deep comparison

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro