Back-channel logout
Back-channel logout lets the provider end this app’s session without the browser’s involvement — when the user logs out at the provider (or their session expires there), the provider POSTs a signed logout token directly to this app. It is opt-in:
OIDC_RP_BACKCHANNEL_LOGOUT_ENABLED=trueEnabling it registers POST /oidc/backchannel-logout and the enforcement middleware, and
starts recording the sid claim from each login’s id_token.
You must register this endpoint as the client’s backchannel_logout_uri at the provider —
providers only POST to URIs they know about. On a laravel-oidc provider that is a column
on the client (see the provider’s logout page).
How teardown works
Section titled “How teardown works”sequenceDiagram
autonumber
participant OP as OIDC provider
participant RP as Your app (relying party)
participant B as Browser
OP->>RP: POST /oidc/backchannel-logout (logout_token)
RP->>RP: Validate the logout token<br/>(typ, signature, iss, aud, events, exp, iat, sid)
RP->>RP: Destroy the session mapped to sid<br/>(server-side session drivers)
RP->>RP: Write a revocation marker to cache
RP->>OP: 200 OK
Note over B,RP: cookie session driver: teardown happens on the next request
B->>RP: Next request carrying the revoked sid
RP->>B: Session invalidated by EnforceBackchannelLogout
Two mechanisms cooperate:
- Immediate teardown. At login the session id is stored in cache under the token’s
sid. When a logout token arrives, that session is destroyed directly through the session handler — the user is logged out before their next request. - The revocation marker. Independently, a
revokedmarker is written to cache. TheEnforceBackchannelLogoutmiddleware checks it on every request and invalidates any session still carrying thatsid— the safety net for the cookie session driver (where there is no server-side session to destroy) and for anything that outlived the direct teardown.
Both entries expire after backchannel_logout.retention_minutes (defaults to
SESSION_LIFETIME), after which the session itself has expired anyway.
Logout-token validation
Section titled “Logout-token validation”The endpoint accepts only tokens that pass all of
the spec’s checks:
a logout+jwt type header, an RS256 signature against the provider’s JWKS, matching
iss and aud, the back-channel logout events claim, no nonce, a valid exp
(within leeway), an iat no older than the leeway plus five minutes, and a non-empty
sid. Anything else gets a 400 invalid_request; the endpoint never reveals whether a
session existed. It responds with Cache-Control: no-store, private either way and is
throttled (throttle:60,1).
Placing the middleware yourself
Section titled “Placing the middleware yourself”EnforceBackchannelLogout is auto-appended to the web middleware group. Set
oidc-client.backchannel_logout.auto_middleware to false and use the
oidc-client.enforce-logout alias to scope it to a subset of routes instead:
Route::middleware(['web', 'oidc-client.enforce-logout'])->group(function () { // ...});