Logout
Copy page
RP-initiated logout (GET|POST /api/oauth/logout) — end the user's EntryBit browser session with a verified id_token_hint, redirect to a registered post_logout_redirect_uri, and the forced-logout-CSRF defense.
Updated
RP-initiated logout ends the user’s EntryBit browser session — the cookie the system browser holds after signing in. It is the OIDC end_session_endpoint (OIDC RP-Initiated Logout 1.0), advertised in discovery.
GET /api/oauth/logout
POST /api/oauth/logoutTwo different logouts. Revoking the refresh token signs your app out (kills its tokens). This endpoint signs the browser session out, so the next
/authorizere-prompts for a password instead of silently reusing the cookie. On shared devices you want both.
Parameters
GET takes query parameters; POST takes the same fields in an application/x-www-form-urlencoded body.
| Parameter | Notes |
|---|---|
id_token_hint | The id_token previously issued to the client. Its signature must verify (it may be expired). Required to actually terminate the session. |
post_logout_redirect_uri | Where to send the browser afterward — must exactly match the client’s registered post-logout list. |
state | Opaque value echoed to the post-logout redirect. |
client_id | Optional; when present it must match the hint’s audience. |
Behavior
The session is terminated only when the id_token_hint:
- verifies — valid signature and issuer (expiry is not required); and
- matches — its
subequals the currently signed-in user.
Then the browser is redirected to post_logout_redirect_uri only if it exactly matches one of the client’s registered post_logout_redirect_uris (a separate allowlist from login redirect URIs — register them in Settings → Team → OAuth apps). When it matches, state is appended. With no hint, an invalid hint, or an unregistered URI, the browser simply lands on the EntryBit home page.
HTTP/1.1 302 Found
Location: entrybitresident://oauth/callback?state=<same>The forced-logout-CSRF defense
The id_token_hint requirement is a security control, not a formality. Without it, a bare cross-site GET /api/oauth/logout embedded in any web page could force-log-out a signed-in user (a logout CSRF). By requiring a verified id_token_hint whose sub matches the current user, EntryBit ensures only a party that already holds the user’s own id_token can end their session — an attacker cannot.
In a native app
Take the endpoint from discovery (end_session_endpoint) rather than hardcoding the path:
import * as AuthSession from 'expo-auth-session';
import * as WebBrowser from 'expo-web-browser';
const { endSessionEndpoint } = await AuthSession.fetchDiscoveryAsync('https://entrybit.net');
if (!endSessionEndpoint) throw new Error('end_session_endpoint not advertised');
const logoutUrl = `${endSessionEndpoint}?${new URLSearchParams({
id_token_hint: idToken, // the id_token from sign-in
post_logout_redirect_uri: redirectUri, // must be REGISTERED as a post-logout URI
})}`;
await WebBrowser.openAuthSessionAsync(logoutUrl, redirectUri);The simplest alternative on shared devices is to sign in with an ephemeral browser session in the first place, so no cookie ever persists:
promptAsync({ preferEphemeralSession: true }); // iOS: no shared Safari cookiesA complete sign-out does both: revoke the refresh token, clear local storage, then hit this endpoint (or use an ephemeral session). See the quickstart.