APP-48Required
Survive an expired session
When a session expires, keep the screen and the unsaved work. Let the person sign in again in place, then repeat the request that failed.
How to do it
For script requests, the server answers 401 with problem details, never a redirect to an HTML sign-in page. The client keeps its state, opens sign-in in a dialog or a new tab, and retries the request once sign-in succeeds. Warn before a timed sign-out and offer more time, as time limits requires. The idle and total session limits are in lock down session cookies.
Examples
TypeScript example
export async function apiFetch(input: string, init?: RequestInit): Promise<Response> {
const response = await fetch(input, init);
if (response.status !== 401) return response;
await signInAgain();
return fetch(input, init);
}
Python example
@app.errorhandler(SessionExpired)
def session_expired(_error):
wants_page = request.accept_mimetypes.best == "text/html" and "HX-Request" not in request.headers
if wants_page:
return redirect(url_for("sign_in", next=request.path))
return problem(401, "session-expired", title="Please sign in again")
How to check
A browser test fills a form, deletes the session cookie and submits. A sign-in prompt appears, and after signing in the form is saved with the values typed before.
Sources
- WCAG 2.2 criterion 2.2.1 Timing Adjustable
- WCAG 2.2 criterion 2.2.5 Re-authenticating
- RFC 9457 Problem Details for HTTP APIs
Related rules
- AXS-36 Give people enough time in Accessibility
- APS-16 Lock down session cookies in Application security
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/app-ui/sessions-and-permissions/session-expiry">Agent Wranglers web app interface playbook</a>. In code you write, add a comment next to it with the same link.