Obexal Docs

Docs/Authentification/Sessions et déconnexion

Sessions et déconnexion

Comment fonctionnent les sessions Obexal (opaques, côté serveur, révocables) et toutes les façons d'y mettre fin : self-service, logout RP-initiated et Back-Channel Logout OIDC.

Une session Obexal n'est pas un JWT posé dans le navigateur : c'est un enregistrement opaque côté serveur, révocable à tout instant, avec effet immédiat. Cette page explique le modèle de session, les contrôles self-service offerts aux utilisateurs, et les deux mécanismes de déconnexion sur lesquels les applications peuvent s'appuyer.

Note

Les exemples utilisent accounts.obexal.com, le domaine par défaut. Avec un domaine personnalisé, remplacez-le.

Comment fonctionnent les sessions

La connexion pose un cookie de session (obexal_session par défaut) : un cookie HttpOnly et Secure contenant un jeton opaque aléatoire de 32 octets, avec SameSite=Lax. Le cookie ne transporte aucune donnée. Côté serveur, seule l'empreinte SHA-256 du jeton est stockée (Redis, avec miroir PostgreSQL) : une fuite de base de données n'expose aucune session exploitable.

L'état vivant sur le serveur, la révocation est instantanée : il n'y a pas de jeton autoporté dont il faudrait attendre l'expiration. La durée de vie par défaut d'une session est de 24 heures, configurable en auto-hébergement.

Certains événements de sécurité révoquent les sessions automatiquement : une réinitialisation de mot de passe et un changement d'e-mail confirmé révoquent toutes les sessions de l'utilisateur ; un changement de mot de passe authentifié révoque toutes les sessions sauf la courante.

Self-service : lister et révoquer ses sessions

Les utilisateurs peuvent voir et fermer leurs propres sessions. Ces endpoints exigent une session valide ; les mutations exigent aussi l'en-tête CSRF (X-CSRF-Token), comme le reste de /v1.

curl -sS -b cookies.txt https://accounts.obexal.com/v1/auth/sessions
{
  "sessions": [
    {
      "id": "c9a1f4e2",
      "device": "Firefox sur Linux",
      "ip": "203.0.113.7",
      "createdAt": "2026-07-01T08:12:00Z",
      "lastSeenAt": "2026-07-02T09:40:00Z",
      "current": true
    }
  ]
}

Révoquer une session, ou tout sauf la courante :

curl -sS -b cookies.txt -X DELETE "https://accounts.obexal.com/v1/auth/sessions/<id>" \
  -H "X-CSRF-Token: $CSRF"
# 204 (révoquer la session courante efface aussi le cookie)

curl -sS -b cookies.txt -X POST https://accounts.obexal.com/v1/auth/sessions/revoke-others \
  -H "X-CSRF-Token: $CSRF"
# 200 -> {"revoked": 3}

GET /v1/auth/login-history complète le tableau avec les connexions récentes de l'utilisateur, réussies comme échouées.

Se déconnecter d'Obexal

POST /v1/auth/logout révoque la session courante, efface le cookie et renvoie 204. L'appel est idempotent : sans session valide, il renvoie aussi 204. Après la révocation, Obexal notifie de façon asynchrone les applications de l'utilisateur via le Back-Channel Logout (voir plus bas).

Logout RP-initiated

GET /oauth/logout est le end_session_endpoint annoncé dans le document de découverte. Une application (RP) y redirige le navigateur de l'utilisateur pour mettre fin à la session Obexal :

https://accounts.obexal.com/oauth/logout?client_id=app_a1b2c3&post_logout_redirect_uri=https%3A%2F%2Fapp.example.eu%2Fcallback&state=xyz

La session est révoquée et le cookie effacé, puis le navigateur est redirigé. La post_logout_redirect_uri n'est honorée que si elle correspond exactement à l'une des redirect URIs enregistrées du client (allowlist, anti open-redirect) ; state, s'il est présent, est renvoyé tel quel sur cette redirection. Sinon, l'utilisateur arrive sur la page de connexion hébergée. L'endpoint n'utilise pas id_token_hint : identifiez le client explicitement avec client_id.

Back-Channel Logout (OIDC)

Pour une vraie déconnexion unique, enregistrez une backchannelLogoutUri sur votre application (champ de POST /v1/applications, ou PATCH ensuite). À la déconnexion de l'utilisateur, Obexal POSTe un logout token signé (form-encoded, champ logout_token) directement à cette URI, de serveur à serveur, pour chaque application avec laquelle l'utilisateur a un consentement. L'envoi est best-effort, via un client HTTP borné en temps et protégé contre le SSRF.

Le logout token est un JWT signé RS256 avec l'en-tête typ: logout+jwt :

{
  "iss": "https://accounts.obexal.com",
  "sub": "8f2c1e9a-4b7d-4c2e-9f1a-3d5e7b9c0a12",
  "aud": "app_a1b2c3",
  "iat": 1751449400,
  "jti": "q4Zr8w...",
  "events": { "http://schemas.openid.net/event/backchannel-logout": {} }
}

À la réception, votre application doit valider la signature via le JWKS, contrôler iss, aud et iat, vérifier le claim events, imposer l'usage unique du jti, puis fermer ses propres sessions locales pour ce sub et répondre 200.

Le document de découverte annonce backchannel_logout_supported: true et backchannel_logout_session_supported: false : la déconnexion est adressée par sub, votre application doit donc fermer toutes les sessions locales de cet utilisateur ; il n'y a pas de claim sid.

Limites

  • Pas de front-channel logout (le mécanisme à base d'iframes) : le Back-Channel Logout est la voie de déconnexion unique supportée.
  • Les logout tokens identifient l'utilisateur (sub), pas une session individuelle (sid).
  • L'envoi back-channel est best-effort : une application injoignable à cet instant n'est pas relancée. Gardez vos sessions locales courtes et validez correctement les access tokens ; voir Valider les jetons.