Version 4.1.0 · All versions

All pages

Authentication

Login, session restore, and logout against a Solid identity provider using Solid-OIDC, which builds on OpenID Connect and DPoP (the specifications and their status are in standards.md). All authentication code lives in packages/solid/src/solidSessionGateway.ts, behind the SessionGateway port.

Login flow

The user enters only their WebID (its profile in Solid; collected by the onboarding flow, validated as an https: URL). The app dereferences it (unauthenticated) and reads the solid:oidcIssuer triple to find their identity provider, then starts the OIDC redirect flow. The issuer is never inferred from the WebID's origin — the two often differ (a WebID on alice.datapod.igrant.io is served by the issuer datapod.igrant.io) — and must itself be an https: URL.

Alternatively the user picks a suggested provider (onboarding); loginWithIssuer then skips the profile lookup and starts the same flow at that issuer.

The app never handles credentials: no password field, no client secret, no hand-rolled OIDC. The authn library registers the client dynamically, under the site's name (VITE_APP_NAME, configuration.md), and runs the authorization-code + PKCE flow.

Logging in with Solid-OIDC
The user enters a WebID, the gateway finds its identity provider, the provider redirects back with a code, and the gateway exchanges the code for a session.
The diagram's source
sequenceDiagram
    accTitle: Logging in with Solid-OIDC
    accDescr: The user enters a WebID, the gateway finds its identity provider, the provider redirects back with a code, and the gateway exchanges the code for a session.
    actor User
    participant UI
    participant Gateway as SolidSessionGateway
    participant Pod as WebID document
    participant IdP as Identity provider

    User->>UI: enter WebID, submit
    UI->>Gateway: login(webId)
    Gateway->>Pod: GET WebID document
    Pod-->>Gateway: profile (solid:oidcIssuer)
    Gateway->>IdP: redirect (authorization request)
    IdP->>User: login + consent
    IdP->>UI: redirect back with code
    Note over UI,Gateway: page reloads
    UI->>Gateway: restore()
    Gateway->>IdP: handleIncomingRedirect (token exchange)
    IdP-->>Gateway: session (WebID)
    Gateway-->>UI: { session: { webId }, origin: "login" }

Session restore

restore() runs on every page load (App's boot effect), through the restoreSession use case, which falls back to a guest's session when a guest studied in this browser (guest-mode.md). It completes a pending OIDC redirect if one is in flight, otherwise silently restores a previous session (restorePreviousSession: true). It returns a domain EstablishedSession ({ session, origin }) or null. origin is "login" when the library emitted its LOGIN event (a login redirect just completed) and "restored" otherwise; the UI shows the "Pod connected" onboarding step only for the former.

Solid Memo and the Studio are one page, so they share this one session (studio.md): a login in either is a login in both. A redirect URL may carry no hash, so the identity provider sends the user back to the site's root, without the route they left from. The gateway puts that route back before restore() returns. On a login, startLogin keeps the hash in sessionStorage (solid-memo:login-hash) and restore() takes it from there. On a silent restore, the library reports the page it left (its SESSION_RESTORED event) and restore() takes the hash from that. Either way it replaces the page's hash and fires hashchange, so the routers follow, as after a link. So a reload comes back to the screen it left, and a login set off at the Studio's landing page (#/studio) comes back to the Studio, not to Solid Memo's decks.

Authenticated requests

Repositories receive fetch by injection. The composition root injects authFetch, a lazy wrapper that delegates to the current default session's fetch at call time — never a reference captured before login — behind a router that sends the guest's URLs to the pod kept in the browser instead (guest-mode.md). Every pod read goes through it, the WebID document's too: the storage gateway hands @inrupt/solid-client the profile it read, since left to itself the library reads it with the browser's own fetch.

Logout

logout() clears the session via the authn library; the UI additionally clears the react-query cache so no pod data outlives the session that fetched it.