Hand over the token
The one thing your page does for Doshi — answer each token request from your backend — and what expiry and logout mean.
Your page’s only job in jwt_sso is to answer Doshi when it asks for a member token,
with a token from your backend. The iframe asks with a doshi:token-request
message and the SDK calls your getToken function, but the contract is the same.
The contract
Section titled “The contract”| Answer with | The access_token string from the token exchange, nothing else. |
| Asked | Before the first screen, then about 20 seconds before each token expires: roughly four times per active hour per member. Not per request. |
| Must be | Idempotent and cheap. Doshi collapses concurrent asks into one. |
| When there is no session | SDK: reject or throw. Iframe: answer with token:. |
Doshi holds the token in memory only, never in localStorage, sessionStorage, a
cookie or the URL. It caches the token and renews it ahead of expiry. You do not need to
cache anything yourself, and you should not: your backend’s job is to mint a fresh token
when asked.
A typical answer fetches from your own backend:
async function getToken() { const res = await fetch("/api/doshi-token", { method: "POST" }); if (!res.ok) throw new Error(`doshi-token: ${res.status}`); const { access_token } = await res.json(); return access_token;}Your /api/doshi-token endpoint must authenticate the caller as your own session holder,
and sign the assertion for that customer. It is the point where your session becomes
a Doshi session, so nothing else may reach it.
Expiry
Section titled “Expiry”If your page cannot answer with a token, because your session has ended or your backend is unreachable, Doshi does three things, once:
- clears its cached token,
- blanks its content, so nothing stale stays on screen,
- tells your page
auth_expired: the SDK callsonError, and the iframe postsdoshi:error. See Events.
After that, Doshi shows “Your session has ended” and waits. It tells you once, not per retry.
Doshi will never show a Doshi login screen to your members. There is no password for them to type, and offering one inside your app would be wrong. If the token flow fails, the member’s route back in is through your app: sign them in again and mount or load Doshi afresh.
Logout
Section titled “Logout”Remove Doshi from your page. That is the whole procedure. With the SDK, call
unmount(). With the iframe, remove the <iframe> element.
The token is memory-only and dies with it. There is no logout endpoint to call, no session to revoke, and no back-channel signal to handle. Building one would be building against an API that does not exist.
A member token lives up to 15 minutes (see the token exchange). Removing Doshi removes the only copy of it, so that is how you end the member’s access at a specific moment rather than at the next renewal.